44
55use super :: {
66 ActionRegistry , NexusActionContext , NexusSaga , SagaInitError ,
7- ACTION_GENERATE_ID ,
7+ ACTION_GENERATE_ID , MAX_CONCURRENT_REGION_REQUESTS ,
88} ;
99use crate :: app:: sagas:: NexusAction ;
1010use crate :: context:: OpContext ;
@@ -51,16 +51,10 @@ lazy_static! {
5151 sdc_create_disk_record,
5252 sdc_create_disk_record_undo
5353 ) ;
54- static ref REGIONS_ALLOC : NexusAction = ActionFunc :: new_action(
55- "disk-create.regions-alloc" ,
56- sdc_alloc_regions,
57- sdc_alloc_regions_undo
58- ) ;
59- static ref REGIONS_ENSURE : NexusAction = ActionFunc :: new_action(
60- "disk-create.regions-ensure" ,
61- sdc_regions_ensure,
62- sdc_regions_ensure_undo
63- ) ;
54+ static ref REGIONS_ALLOC : NexusAction =
55+ new_action_noop_undo( "disk-create.regions-alloc" , sdc_alloc_regions, ) ;
56+ static ref REGIONS_ENSURE : NexusAction =
57+ new_action_noop_undo( "disk-create.regions-ensure" , sdc_regions_ensure, ) ;
6458 static ref CREATE_VOLUME_RECORD : NexusAction = ActionFunc :: new_action(
6559 "disk-create.create-volume-record" ,
6660 sdc_create_volume_record,
@@ -231,6 +225,7 @@ async fn sdc_alloc_regions(
231225 let osagactx = sagactx. user_data ( ) ;
232226 let params = sagactx. saga_params :: < Params > ( ) ?;
233227 let volume_id = sagactx. lookup :: < Uuid > ( "volume_id" ) ?;
228+
234229 // Ensure the disk is backed by appropriate regions.
235230 //
236231 // This allocates regions in the database, but the disk state is still
@@ -251,16 +246,7 @@ async fn sdc_alloc_regions(
251246 Ok ( datasets_and_regions)
252247}
253248
254- async fn sdc_alloc_regions_undo (
255- sagactx : NexusActionContext ,
256- ) -> Result < ( ) , anyhow:: Error > {
257- let osagactx = sagactx. user_data ( ) ;
258-
259- let volume_id = sagactx. lookup :: < Uuid > ( "volume_id" ) ?;
260- osagactx. datastore ( ) . regions_hard_delete ( volume_id) . await ?;
261- Ok ( ( ) )
262- }
263-
249+ /// Call out to Crucible agent and perform region creation.
264250async fn ensure_region_in_dataset (
265251 log : & Logger ,
266252 dataset : & db:: model:: Dataset ,
@@ -317,10 +303,7 @@ async fn ensure_region_in_dataset(
317303 Ok ( region. into_inner ( ) )
318304}
319305
320- // Arbitrary limit on concurrency, for operations issued
321- // on multiple regions within a disk at the same time.
322- const MAX_CONCURRENT_REGION_REQUESTS : usize = 3 ;
323-
306+ /// Call out to Crucible agent and perform region creation.
324307async fn sdc_regions_ensure (
325308 sagactx : NexusActionContext ,
326309) -> Result < String , ActionError > {
@@ -379,7 +362,7 @@ async fn sdc_regions_ensure(
379362
380363 let block_size = datasets_and_regions[ 0 ] . 1 . block_size ;
381364
382- // If requested, back disk by image
365+ // If a disk source was requested, set the read-only parent of this disk.
383366 let osagactx = sagactx. user_data ( ) ;
384367 let params = sagactx. saga_params :: < Params > ( ) ?;
385368 let log = osagactx. log ( ) ;
@@ -497,7 +480,7 @@ async fn sdc_regions_ensure(
497480 ) ;
498481 }
499482
500- // Store volume details in db
483+ // Create volume construction request for this disk
501484 let mut rng = StdRng :: from_entropy ( ) ;
502485 let volume_construction_request = VolumeConstructionRequest :: Volume {
503486 id : disk_id,
@@ -554,55 +537,6 @@ async fn sdc_regions_ensure(
554537 Ok ( volume_data)
555538}
556539
557- pub ( super ) async fn delete_regions (
558- datasets_and_regions : Vec < ( db:: model:: Dataset , db:: model:: Region ) > ,
559- ) -> Result < ( ) , Error > {
560- let request_count = datasets_and_regions. len ( ) ;
561- futures:: stream:: iter ( datasets_and_regions)
562- . map ( |( dataset, region) | async move {
563- let url = format ! ( "http://{}" , dataset. address( ) ) ;
564- let client = CrucibleAgentClient :: new ( & url) ;
565- let id = RegionId ( region. id ( ) . to_string ( ) ) ;
566- client. region_delete ( & id) . await . map_err ( |e| match e {
567- crucible_agent_client:: Error :: ErrorResponse ( rv) => {
568- match rv. status ( ) {
569- http:: StatusCode :: SERVICE_UNAVAILABLE => {
570- Error :: unavail ( & rv. message )
571- }
572- status if status. is_client_error ( ) => {
573- Error :: invalid_request ( & rv. message )
574- }
575- _ => Error :: internal_error ( & rv. message ) ,
576- }
577- }
578- _ => Error :: internal_error (
579- "unexpected failure during `region_delete`" ,
580- ) ,
581- } )
582- } )
583- // Execute the allocation requests concurrently.
584- . buffer_unordered ( std:: cmp:: min (
585- request_count,
586- MAX_CONCURRENT_REGION_REQUESTS ,
587- ) )
588- . collect :: < Vec < Result < _ , _ > > > ( )
589- . await
590- . into_iter ( )
591- . collect :: < Result < Vec < _ > , _ > > ( ) ?;
592- Ok ( ( ) )
593- }
594-
595- async fn sdc_regions_ensure_undo (
596- sagactx : NexusActionContext ,
597- ) -> Result < ( ) , anyhow:: Error > {
598- let datasets_and_regions = sagactx
599- . lookup :: < Vec < ( db:: model:: Dataset , db:: model:: Region ) > > (
600- "datasets_and_regions" ,
601- ) ?;
602- delete_regions ( datasets_and_regions) . await ?;
603- Ok ( ( ) )
604- }
605-
606540async fn sdc_create_volume_record (
607541 sagactx : NexusActionContext ,
608542) -> Result < db:: model:: Volume , ActionError > {
@@ -628,7 +562,7 @@ async fn sdc_create_volume_record_undo(
628562 let osagactx = sagactx. user_data ( ) ;
629563
630564 let volume_id = sagactx. lookup :: < Uuid > ( "volume_id" ) ?;
631- osagactx. datastore ( ) . volume_delete ( volume_id) . await ?;
565+ osagactx. nexus ( ) . volume_delete ( volume_id) . await ?;
632566 Ok ( ( ) )
633567}
634568
@@ -647,6 +581,7 @@ async fn sdc_finalize_disk_record(
647581 . lookup_for ( authz:: Action :: Modify )
648582 . await
649583 . map_err ( ActionError :: action_failed) ?;
584+
650585 // TODO-security Review whether this can ever fail an authz check. We don't
651586 // want this to ever fail the authz check here -- if it did, we would have
652587 // wanted to catch that a lot sooner. It wouldn't make sense for it to fail
@@ -665,6 +600,7 @@ async fn sdc_finalize_disk_record(
665600 )
666601 . await
667602 . map_err ( ActionError :: action_failed) ?;
603+
668604 Ok ( ( ) )
669605}
670606
0 commit comments