diff --git a/lib/propolis/src/block/crucible.rs b/lib/propolis/src/block/crucible.rs index 4adc085dd..f0cfdb26e 100644 --- a/lib/propolis/src/block/crucible.rs +++ b/lib/propolis/src/block/crucible.rs @@ -168,7 +168,10 @@ impl CrucibleBackend { .map_err(|e| io::Error::from(CrucibleError::from(e)))?; // Decide if we need to scrub this volume or not. - if volume.has_read_only_parent() { + // + // We should not scrub read-only volumes, as we cannot write back to + // them, due to...you know, being read-only. So just don't do that. + if !opts.is_read_only() && volume.has_read_only_parent() { let vclone = volume.clone(); tokio::spawn(async move { let volume_id = vclone.get_uuid().await.unwrap(); @@ -217,7 +220,7 @@ impl CrucibleBackend { let info = block::DeviceInfo { block_size: block_size as u32, total_size: sectors, - read_only: opts.read_only.unwrap_or(false), + read_only: opts.is_read_only(), supports_discard: false, }; diff --git a/lib/propolis/src/block/mod.rs b/lib/propolis/src/block/mod.rs index 5d79c0119..ccc183f8b 100644 --- a/lib/propolis/src/block/mod.rs +++ b/lib/propolis/src/block/mod.rs @@ -275,6 +275,13 @@ pub struct BackendOpts { pub skip_flush: Option, } +impl BackendOpts { + /// Return `true` if and only if this backend is configured to be read-only. + pub fn is_read_only(&self) -> bool { + self.read_only.unwrap_or(false) + } +} + /// Top-level trait for block devices (frontends) to translate guest block IO /// requests into [Request]s for the attached [Backend] pub trait Device: Send + Sync + 'static {