pub async fn probe_label(&self) -> Result<NexusLabel, LabelError> {
        let hndl = self.handle().context(ReadError {
            name: self.name.clone(),
        })?;
        let bdev = hndl.get_bdev();
        let block_size = hndl.get_bdev().block_len() as u64;

        // Protective MBR
        let mut buf = hndl.dma_malloc(block_size).context(ReadAlloc {
            name: String::from("header"),
        })?;
        hndl.read_at(0, &mut buf).await.context(ReadError {
            name: String::from("MBR"),
        })?;
        let mbr = NexusLabel::read_mbr(&buf)?;

        let status: NexusLabelStatus;
        let primary: GPTHeader;
        let secondary: GPTHeader;
        let active: &GPTHeader;

        //
        // GPT header(s)

        // Get primary.
        hndl.read_at(block_size, &mut buf)
            .await
            .context(ReadError {
                name: String::from("primary GPT header"),
            })?;
        match NexusLabel::read_primary_header(&buf) {
            Ok(header) => {
                primary = header;
                active = &primary;
                // Get secondary.
                let offset = (bdev.num_blocks() - 1) * block_size;
                hndl.read_at(offset, &mut buf).await.context(ReadError {
                    name: String::from("secondary GPT header"),
                })?;
                match NexusLabel::read_secondary_header(&buf) {
                    Ok(header) => {
                        // Both primary and secondary GPT headers are valid.
                        // Check if they are consistent with each other.
                        match NexusLabel::check_consistency(&primary, &header) {
                            Ok(()) => {
                                // All good.
                                secondary = header;
                                status = NexusLabelStatus::Both;
                            }
                            Err(error) => {
                                warn!("{}: {}: The primary and secondary GPT headers are inconsistent: {}", self.parent, self.name, error);
                                warn!("{}: {}: Recreating secondary GPT header from primary!", self.parent, self.name);
                                secondary = primary.to_backup();
                                status = NexusLabelStatus::Primary;
                            }
                        }
                    }
                    Err(error) => {
                        warn!(
                            "{}: {}: The secondary GPT header is invalid: {}",
                            self.parent, self.name, error
                        );
                        warn!("{}: {}: Recreating secondary GPT header from primary!", self.parent, self.name);
                        secondary = primary.to_backup();
                        status = NexusLabelStatus::Primary;
                    }
                }
            }
            Err(error) => {
                warn!(
                    "{}: {}: The primary GPT header is invalid: {}",
                    self.parent, self.name, error
                );
                // Get secondary and see if we are able to proceed.
                let offset = (bdev.num_blocks() - 1) * block_size;
                hndl.read_at(offset, &mut buf).await.context(ReadError {
                    name: String::from("secondary GPT header"),
                })?;
                match NexusLabel::read_secondary_header(&buf) {
                    Ok(header) => {
                        secondary = header;
                        active = &secondary;
                        warn!("{}: {}: Recreating primary GPT header from secondary!", self.parent, self.name);
                        primary = secondary.to_primary();
                        status = NexusLabelStatus::Secondary;
                    }
                    Err(error) => {
                        warn!(
                            "{}: {}: The secondary GPT header is invalid: {}",
                            self.parent, self.name, error
                        );
                        warn!("{}: {}: Both primary and secondary GPT headers are invalid!", self.parent, self.name);
                        return Err(LabelError::LabelInvalid {});
                    }
                }
            }
        }

        if mbr.entries[0].num_sectors != 0xffff_ffff
            && mbr.entries[0].num_sectors as u64 != primary.lba_alt
        {
            warn!("{}: {}: The protective MBR disk size does not match the GPT disk size!", self.parent, self.name);
            return Err(LabelError::LabelInvalid {});
        }

        //
        // Partition table
        let blocks = Aligned::get_blocks(
            (active.entry_size * active.num_entries) as u64,
            block_size,
        );
        let mut buf =
            hndl.dma_malloc(blocks * block_size).context(ReadAlloc {
                name: String::from("partition table"),
            })?;
        let offset = active.lba_table * block_size;
        hndl.read_at(offset, &mut buf).await.context(ReadError {
            name: String::from("partition table"),
        })?;
        let mut partitions = NexusLabel::read_partitions(&buf, active)?;

        // Some tools always write 128 partition entries, even though most
        // are not used. In any case we are only ever interested
        // in the first two partitions, so we drain the others.
        let entries = partitions.drain(.. 2).collect::<Vec<GptEntry>>();

        Ok(NexusLabel {
            status,
            mbr,
            primary,
            partitions: entries,
            secondary,
        })
    }
/// read and validate this child's label
read and validate this child's label
read and validate this child ' s label
pub async fn probe_label(&self) -> Result<NexusLabel, LabelError> {
        let hndl = self.handle().context(ReadError {
            name: self.name.clone(),
        })?;
        let bdev = hndl.get_bdev();
        let block_size = hndl.get_bdev().block_len() as u64;
        // Protective MBR
        let mut buf = hndl.dma_malloc(block_size).context(ReadAlloc {
            name: String::from("header"),
        })?;
        hndl.read_at(0, &mut buf).await.context(ReadError {
            name: String::from("MBR"),
        })?;
        let mbr = NexusLabel::read_mbr(&buf)?;
        let status: NexusLabelStatus;
        let primary: GPTHeader;
        let secondary: GPTHeader;
        let active: &GPTHeader;
        //
        // GPT header(s)
        // Get primary.
        hndl.read_at(block_size, &mut buf)
            .await
            .context(ReadError {
                name: String::from("primary GPT header"),
            })?;
        match NexusLabel::read_primary_header(&buf) {
            Ok(header) => {
                primary = header;
                active = &primary;
                // Get secondary.
                let offset = (bdev.num_blocks() - 1) * block_size;
                hndl.read_at(offset, &mut buf).await.context(ReadError {
                    name: String::from("secondary GPT header"),
                })?;
                match NexusLabel::read_secondary_header(&buf) {
                    Ok(header) => {
                        // Both primary and secondary GPT headers are valid.
                        // Check if they are consistent with each other.
                        match NexusLabel::check_consistency(&primary, &header) {
                            Ok(()) => {
                                // All good.
                                secondary = header;
                                status = NexusLabelStatus::Both;
                            }
                            Err(error) => {
                                warn!("{}: {}: The primary and secondary GPT headers are inconsistent: {}", self.parent, self.name, error);
                                warn!("{}: {}: Recreating secondary GPT header from primary!", self.parent, self.name);
                                secondary = primary.to_backup();
                                status = NexusLabelStatus::Primary;
                            }
                        }
                    }
                    Err(error) => {
                        warn!(
                            "{}: {}: The secondary GPT header is invalid: {}",
                            self.parent, self.name, error
                        );
                        warn!("{}: {}: Recreating secondary GPT header from primary!", self.parent, self.name);
                        secondary = primary.to_backup();
                        status = NexusLabelStatus::Primary;
                    }
                }
            }
            Err(error) => {
                warn!(
                    "{}: {}: The primary GPT header is invalid: {}",
                    self.parent, self.name, error
                );
                // Get secondary and see if we are able to proceed.
                let offset = (bdev.num_blocks() - 1) * block_size;
                hndl.read_at(offset, &mut buf).await.context(ReadError {
                    name: String::from("secondary GPT header"),
                })?;
                match NexusLabel::read_secondary_header(&buf) {
                    Ok(header) => {
                        secondary = header;
                        active = &secondary;
                        warn!("{}: {}: Recreating primary GPT header from secondary!", self.parent, self.name);
                        primary = secondary.to_primary();
                        status = NexusLabelStatus::Secondary;
                    }
                    Err(error) => {
                        warn!(
                            "{}: {}: The secondary GPT header is invalid: {}",
                            self.parent, self.name, error
                        );
                        warn!("{}: {}: Both primary and secondary GPT headers are invalid!", self.parent, self.name);
                        return Err(LabelError::LabelInvalid {});
                    }
                }
            }
        }
        if mbr.entries[0].num_sectors != 0xffff_ffff
            && mbr.entries[0].num_sectors as u64 != primary.lba_alt
        {
            warn!("{}: {}: The protective MBR disk size does not match the GPT disk size!", self.parent, self.name);
            return Err(LabelError::LabelInvalid {});
        }
        //
        // Partition table
        let blocks = Aligned::get_blocks(
            (active.entry_size * active.num_entries) as u64,
            block_size,
        );
        let mut buf =
            hndl.dma_malloc(blocks * block_size).context(ReadAlloc {
                name: String::from("partition table"),
            })?;
        let offset = active.lba_table * block_size;
        hndl.read_at(offset, &mut buf).await.context(ReadError {
            name: String::from("partition table"),
        })?;
        let mut partitions = NexusLabel::read_partitions(&buf, active)?;
        // Some tools always write 128 partition entries, even though most
        // are not used. In any case we are only ever interested
        // in the first two partitions, so we drain the others.
        let entries = partitions.drain(.. 2).collect::<Vec<GptEntry>>();
        Ok(NexusLabel {
            status,
            mbr,
            primary,
            partitions: entries,
            secondary,
        })
    }
pub async fn probe_label ( & self ) -> Result < NexusLabel , LabelError > { let hndl = self . handle ( ) . context ( ReadError { name : self . name . clone ( ) , } ) ? ; let bdev = hndl . get_bdev ( ) ; let block_size = hndl . get_bdev ( ) . block_len ( ) as u64 ; // Protective MBR let mut buf = hndl . dma_malloc ( block_size ) . context ( ReadAlloc { name : String :: from ( " " ) , } ) ? ; hndl . read_at ( 0 , & mut buf ) . await . context ( ReadError { name : String :: from ( " " ) , } ) ? ; let mbr = NexusLabel :: read_mbr ( & buf ) ? ; let status : NexusLabelStatus ; let primary : GPTHeader ; let secondary : GPTHeader ; let active : & GPTHeader ; // // GPT header(s) // Get primary. hndl . read_at ( block_size , & mut buf ) . await . context ( ReadError { name : String :: from ( " " ) , } ) ? ; match NexusLabel :: read_primary_header ( & buf ) { Ok ( header ) => { primary = header ; active = & primary ; // Get secondary. let offset = ( bdev . num_blocks ( ) - 1 ) * block_size ; hndl . read_at ( offset , & mut buf ) . await . context ( ReadError { name : String :: from ( " " ) , } ) ? ; match NexusLabel :: read_secondary_header ( & buf ) { Ok ( header ) => { // Both primary and secondary GPT headers are valid. // Check if they are consistent with each other. match NexusLabel :: check_consistency ( & primary , & header ) { Ok ( ( ) ) => { // All good. secondary = header ; status = NexusLabelStatus :: Both ; } Err ( error ) => { warn ! ( " " self parent self name error ) ; warn ! ( " " self parent self name ) ; secondary = primary . to_backup ( ) ; status = NexusLabelStatus :: Primary ; } } } Err ( error ) => { warn ! ( " " self parent self name error ) ; warn ! ( " " self parent self name ) ; secondary = primary . to_backup ( ) ; status = NexusLabelStatus :: Primary ; } } } Err ( error ) => { warn ! ( " " self parent self name error ) ; // Get secondary and see if we are able to proceed. let offset = ( bdev . num_blocks ( ) - 1 ) * block_size ; hndl . read_at ( offset , & mut buf ) . await . context ( ReadError { name : String :: from ( " " ) , } ) ? ; match NexusLabel :: read_secondary_header ( & buf ) { Ok ( header ) => { secondary = header ; active = & secondary ; warn ! ( " " self parent self name ) ; primary = secondary . to_primary ( ) ; status = NexusLabelStatus :: Secondary ; } Err ( error ) => { warn ! ( " " self parent self name error ) ; warn ! ( " " self parent self name ) ; return Err ( LabelError :: LabelInvalid { } ) ; } } } } if mbr . entries [ 0 ] . num_sectors != 0xffff_ffff && mbr . entries [ 0 ] . num_sectors as u64 != primary . lba_alt { warn ! ( " " self parent self name ) ; return Err ( LabelError :: LabelInvalid { } ) ; } // // Partition table let blocks = Aligned :: get_blocks ( ( active . entry_size * active . num_entries ) as u64 , block_size , ) ; let mut buf = hndl . dma_malloc ( blocks * block_size ) . context ( ReadAlloc { name : String :: from ( " " ) , } ) ? ; let offset = active . lba_table * block_size ; hndl . read_at ( offset , & mut buf ) . await . context ( ReadError { name : String :: from ( " " ) , } ) ? ; let mut partitions = NexusLabel :: read_partitions ( & buf , active ) ? ; // Some tools always write 128 partition entries, even though most // are not used. In any case we are only ever interested // in the first two partitions, so we drain the others. let entries = partitions . drain ( .. 2 ) . collect :: < Vec < GptEntry > > ( ) ; Ok ( NexusLabel { status , mbr , primary , partitions : entries , secondary , } ) }
read and validate this child's label
read and validate this child ' s label
&self