/// Starts a rebuild job and returns a receiver channel
/// which can be used to await the rebuild completion
Starts a rebuild job and returns a receiver channel
which can be used to await the rebuild completion
Starts a rebuild job and returns a receiver channel which can be used to await the rebuild completion
pub async fn start_rebuild(
        &mut self,
        name: &str,
    ) -> Result<Receiver<RebuildState>, Error> {
        trace!("{}: start rebuild request for {}", self.name, name);
        let src_child_name = match self
            .children
            .iter()
            .find(|c| c.state == ChildState::Open && c.name != name)
        {
            Some(child) => Ok(child.name.clone()),
            None => Err(Error::NoRebuildSource {
                name: self.name.clone(),
            }),
        }?;
        let dst_child_name =
            match self.children.iter_mut().find(|c| c.name == name) {
                Some(c) if c.status() == ChildStatus::Degraded => {
                    Ok(c.name.clone())
                }
                Some(c) => Err(Error::ChildNotDegraded {
                    child: name.to_owned(),
                    name: self.name.clone(),
                    state: c.status().to_string(),
                }),
                None => Err(Error::ChildNotFound {
                    child: name.to_owned(),
                    name: self.name.clone(),
                }),
            }?;
        let job = RebuildJob::create(
            &self.name,
            &src_child_name,
            &dst_child_name,
            std::ops::Range::<u64> {
                start: self.data_ent_offset,
                end: self.bdev.num_blocks() + self.data_ent_offset,
            },
            |nexus, job| {
                Reactors::current().send_future(async move {
                    Nexus::notify_rebuild(nexus, job).await;
                });
            },
        )
        .context(CreateRebuildError {
            child: name.to_owned(),
            name: self.name.clone(),
        })?;
        // We're now rebuilding the `dst_child` which means it HAS to become an
        // active participant in the frontend nexus bdev for Writes.
        // This is because the rebuild job copies from src to target child
        // sequentially, from start to the end.
        // This means any Write frontend IO to a range which has already been
        // rebuilt would then need to be rebuilt again.
        // Ensuring that the dst child receives all frontend Write IO keeps all
        // rebuilt ranges in sync with the other children.
        self.reconfigure(DREvent::ChildRebuild).await;
        job.as_client().start().context(RebuildOperationError {
            job: name.to_owned(),
            name: self.name.clone(),
        })
    }
pub async fn start_rebuild ( & mut self , name : & str , ) -> Result < Receiver < RebuildState > , Error > { trace ! ( " " self name name ) ; let src_child_name = match self . children . iter ( ) . find ( | c | c . state == ChildState :: Open && c . name != name ) { Some ( child ) => Ok ( child . name . clone ( ) ) , None => Err ( Error :: NoRebuildSource { name : self . name . clone ( ) , } ) , } ? ; let dst_child_name = match self . children . iter_mut ( ) . find ( | c | c . name == name ) { Some ( c ) if c . status ( ) == ChildStatus :: Degraded => { Ok ( c . name . clone ( ) ) } Some ( c ) => Err ( Error :: ChildNotDegraded { child : name . to_owned ( ) , name : self . name . clone ( ) , state : c . status ( ) . to_string ( ) , } ) , None => Err ( Error :: ChildNotFound { child : name . to_owned ( ) , name : self . name . clone ( ) , } ) , } ? ; let job = RebuildJob :: create ( & self . name , & src_child_name , & dst_child_name , std :: ops :: Range :: < u64 > { start : self . data_ent_offset , end : self . bdev . num_blocks ( ) + self . data_ent_offset , } , | nexus , job | { Reactors :: current ( ) . send_future ( async move { Nexus :: notify_rebuild ( nexus , job ) . await ; } ) ; } , ) . context ( CreateRebuildError { child : name . to_owned ( ) , name : self . name . clone ( ) , } ) ? ; // We're now rebuilding the `dst_child` which means it HAS to become an // active participant in the frontend nexus bdev for Writes. // This is because the rebuild job copies from src to target child // sequentially, from start to the end. // This means any Write frontend IO to a range which has already been // rebuilt would then need to be rebuilt again. // Ensuring that the dst child receives all frontend Write IO keeps all // rebuilt ranges in sync with the other children. self . reconfigure ( DREvent :: ChildRebuild ) . await ; job . as_client ( ) . start ( ) . context ( RebuildOperationError { job : name . to_owned ( ) , name : self . name . clone ( ) , } ) }
Starts a rebuild job and returns a receiver channel
which can be used to await the rebuild completion
Starts a rebuild job and returns a receiver channel which can be used to await the rebuild completion
&mut self
name
&str