diff --git a/pageserver/src/http/routes.rs b/pageserver/src/http/routes.rs index 0dda6a29f964..b4220d160198 100644 --- a/pageserver/src/http/routes.rs +++ b/pageserver/src/http/routes.rs @@ -162,7 +162,6 @@ impl From for ApiError { ApiError::NotFound(anyhow::anyhow!("Tenant {tenant_id} not found").into()) } e @ AlreadyExists(_, _) => ApiError::Conflict(format!("{e}")), - e @ Conflict(_) => ApiError::Conflict(format!("{e}")), InProgress => { ApiError::ResourceUnavailable("Tenant is being modified concurrently".into()) } @@ -195,7 +194,6 @@ impl From for ApiError { impl From for ApiError { fn from(tse: TenantStateError) -> ApiError { match tse { - TenantStateError::NotFound(tid) => ApiError::NotFound(anyhow!("tenant {}", tid).into()), TenantStateError::NotActive(_) => { ApiError::ResourceUnavailable("Tenant not yet active".into()) } diff --git a/pageserver/src/tenant/mgr.rs b/pageserver/src/tenant/mgr.rs index ceadddeb7ebd..c46de7acb71d 100644 --- a/pageserver/src/tenant/mgr.rs +++ b/pageserver/src/tenant/mgr.rs @@ -860,8 +860,6 @@ pub(crate) async fn delete_timeline( #[derive(Debug, thiserror::Error)] pub(crate) enum TenantStateError { - #[error("Tenant {0} not found")] - NotFound(TenantId), #[error("Tenant {0} is stopping")] IsStopping(TenantId), #[error("Tenant {0} is not active")] @@ -930,7 +928,12 @@ async fn detach_tenant0( // Ignored tenants are not present in memory and will bail the removal from memory operation. // Before returning the error, check for ignored tenant removal case — we only need to clean its local files then. - if detach_ignored && matches!(removal_result, Err(TenantStateError::NotFound(_))) { + if detach_ignored + && matches!( + removal_result, + Err(TenantStateError::SlotError(TenantSlotError::NotFound(_))) + ) + { let tenant_ignore_mark = conf.tenant_ignore_mark_file_path(&tenant_id); if tenant_ignore_mark.exists() { info!("Detaching an ignored tenant"); @@ -1124,9 +1127,6 @@ pub(crate) enum TenantSlotError { #[error("tenant {0} already exists, state: {1:?}")] AlreadyExists(TenantId, TenantState), - #[error("tenant {0} already exists in but is not attached")] - Conflict(TenantId), - // Tried to read a slot that is currently being mutated by another administrative // operation. #[error("tenant has a state change in progress, try again later")] @@ -1362,7 +1362,13 @@ where // The SlotGuard allows us to manipulate the Tenant object without fear of some // concurrent API request doing something else for the same tenant ID. let attached_tenant = match tenant_slot { - Some(TenantSlot::Attached(t)) => Some(t), + Some(TenantSlot::Attached(t)) => { + if t.current_state() != TenantState::Active { + tenant_guard.upsert(TenantSlot::Attached(t))?; + return Err(TenantStateError::NotActive(tenant_id)); + } + Some(t) + } _ => None, };