diff --git a/nexus/db-queries/src/db/datastore/region.rs b/nexus/db-queries/src/db/datastore/region.rs index 885cb622b8..8e59462aa3 100644 --- a/nexus/db-queries/src/db/datastore/region.rs +++ b/nexus/db-queries/src/db/datastore/region.rs @@ -422,8 +422,8 @@ impl DataStore { } } - /// Find regions on expunged disks - pub async fn find_regions_on_expunged_physical_disks( + /// Find read/write regions on expunged disks + pub async fn find_read_write_regions_on_expunged_physical_disks( &self, opctx: &OpContext, ) -> LookupResult> { @@ -450,6 +450,8 @@ impl DataStore { )) .select(dataset_dsl::id) )) + // only return read-write regions here + .filter(region_dsl::read_only.eq(false)) .select(Region::as_select()) .load_async(&*conn) .await diff --git a/nexus/db-queries/src/db/datastore/region_replacement.rs b/nexus/db-queries/src/db/datastore/region_replacement.rs index 0fda6b46ba..0d259ba47e 100644 --- a/nexus/db-queries/src/db/datastore/region_replacement.rs +++ b/nexus/db-queries/src/db/datastore/region_replacement.rs @@ -37,6 +37,13 @@ impl DataStore { opctx: &OpContext, region: &Region, ) -> Result { + if region.read_only() { + return Err(Error::invalid_request(format!( + "region {} is read-only", + region.id(), + ))); + } + let request = RegionReplacement::for_region(region); let request_id = request.id; diff --git a/nexus/src/app/background/tasks/region_replacement.rs b/nexus/src/app/background/tasks/region_replacement.rs index f86ba8eb8f..71b49c5a6f 100644 --- a/nexus/src/app/background/tasks/region_replacement.rs +++ b/nexus/src/app/background/tasks/region_replacement.rs @@ -68,17 +68,18 @@ impl BackgroundTask for RegionReplacementDetector { let mut status = RegionReplacementStatus::default(); - // Find regions on expunged physical disks + // Find read/write regions on expunged physical disks let regions_to_be_replaced = match self .datastore - .find_regions_on_expunged_physical_disks(opctx) + .find_read_write_regions_on_expunged_physical_disks(opctx) .await { Ok(regions) => regions, Err(e) => { let s = format!( - "find_regions_on_expunged_physical_disks failed: {e}" + "find_read_write_regions_on_expunged_physical_disks \ + failed: {e}" ); error!(&log, "{s}"); status.errors.push(s); diff --git a/nexus/tests/integration_tests/disks.rs b/nexus/tests/integration_tests/disks.rs index e381146fc0..db16113dd7 100644 --- a/nexus/tests/integration_tests/disks.rs +++ b/nexus/tests/integration_tests/disks.rs @@ -2577,7 +2577,7 @@ async fn test_disk_expunge(cptestctx: &ControlPlaneTestContext) { // All three regions should be returned let expunged_regions = datastore - .find_regions_on_expunged_physical_disks(&opctx) + .find_read_write_regions_on_expunged_physical_disks(&opctx) .await .unwrap();