fn create_memory_regions_from_zones(
        ram_regions: &[(GuestAddress, usize)],
        zones: &[MemoryZoneConfig],
        prefault: bool,
    ) -> Result<(Vec<Arc<GuestRegionMmap>>, MemoryZones), Error> {
        let mut zones = zones.to_owned();
        let mut mem_regions = Vec::new();
        let mut zone = zones.remove(0);
        let mut zone_offset = 0;
        let mut memory_zones = HashMap::new();

        // Add zone id to the list of memory zones.
        memory_zones.insert(zone.id.clone(), MemoryZone::default());

        for ram_region in ram_regions.iter() {
            let mut ram_region_offset = 0;
            let mut exit = false;

            loop {
                let mut ram_region_consumed = false;
                let mut pull_next_zone = false;

                let ram_region_sub_size = ram_region.1 - ram_region_offset;
                let zone_sub_size = zone.size as usize - zone_offset;

                let file_offset = zone_offset as u64;
                let region_start = ram_region
                    .0
                    .checked_add(ram_region_offset as u64)
                    .ok_or(Error::GuestAddressOverFlow)?;
                let region_size = if zone_sub_size <= ram_region_sub_size {
                    if zone_sub_size == ram_region_sub_size {
                        ram_region_consumed = true;
                    }

                    ram_region_offset += zone_sub_size;
                    pull_next_zone = true;

                    zone_sub_size
                } else {
                    zone_offset += ram_region_sub_size;
                    ram_region_consumed = true;

                    ram_region_sub_size
                };

                let region = MemoryManager::create_ram_region(
                    &zone.file,
                    file_offset,
                    region_start,
                    region_size,
                    prefault,
                    zone.shared,
                    zone.hugepages,
                    zone.host_numa_node,
                )?;

                // Add region to the list of regions associated with the
                // current memory zone.
                if let Some(memory_zone) = memory_zones.get_mut(&zone.id) {
                    memory_zone.regions.push(region.clone());
                }

                mem_regions.push(region);

                if pull_next_zone {
                    // Get the next zone and reset the offset.
                    zone_offset = 0;
                    if zones.is_empty() {
                        exit = true;
                        break;
                    }
                    zone = zones.remove(0);

                    // Check if zone id already exist. In case it does, throw
                    // an error as we need unique identifiers. Otherwise, add
                    // the new zone id to the list of memory zones.
                    if memory_zones.contains_key(&zone.id) {
                        error!(
                            "Memory zone identifier '{}' found more than once. \
                            It must be unique",
                            zone.id,
                        );
                        return Err(Error::DuplicateZoneId);
                    }
                    memory_zones.insert(zone.id.clone(), MemoryZone::default());
                }

                if ram_region_consumed {
                    break;
                }
            }

            if exit {
                break;
            }
        }

        Ok((mem_regions, memory_zones))
    }
/// Creates all memory regions based on the available RAM ranges defined
/// by `ram_regions`, and based on the description of the memory zones.
/// In practice, this function can perform multiple memory mappings of the
/// same backing file if there's a hole in the address space between two
/// RAM ranges.
/// One example might be ram_regions containing 2 regions (0-3G and 4G-6G)
/// and zones containing two zones (size 1G and size 4G).
/// This function will create 3 resulting memory regions:
/// - First one mapping entirely the first memory zone on 0-1G range
/// - Second one mapping partially the second memory zone on 1G-3G range
/// - Third one mapping partially the second memory zone on 4G-6G range
Creates all memory regions based on the available RAM ranges defined
by `ram_regions`, and based on the description of the memory zones.
In practice, this function can perform multiple memory mappings of the
same backing file if there's a hole in the address space between two
RAM ranges.
One example might be ram_regions containing 2 regions (0-3G and 4G-6G)
and zones containing two zones (size 1G and size 4G).
This function will create 3 resulting memory regions:
First one mapping entirely the first memory zone on 0-1G range
Second one mapping partially the second memory zone on 1G-3G range
Third one mapping partially the second memory zone on 4G-6G range
Creates all memory regions based on the available RAM ranges defined by ` ram_regions ` and based on the description of the memory zones . In practice this function can perform multiple memory mappings of the same backing file if there ' s a hole in the address space between two RAM ranges . One example might be ram_regions containing 2 regions ( 0 - 3G and 4G - 6G ) and zones containing two zones ( size 1G and size 4G ) . This function will create 3 resulting memory regions : First one mapping entirely the first memory zone on 0 - 1G range Second one mapping partially the second memory zone on 1G - 3G range Third one mapping partially the second memory zone on 4G - 6G range
fn create_memory_regions_from_zones(
        ram_regions: &[(GuestAddress, usize)],
        zones: &[MemoryZoneConfig],
        prefault: bool,
    ) -> Result<(Vec<Arc<GuestRegionMmap>>, MemoryZones), Error> {
        let mut zones = zones.to_owned();
        let mut mem_regions = Vec::new();
        let mut zone = zones.remove(0);
        let mut zone_offset = 0;
        let mut memory_zones = HashMap::new();
        // Add zone id to the list of memory zones.
        memory_zones.insert(zone.id.clone(), MemoryZone::default());
        for ram_region in ram_regions.iter() {
            let mut ram_region_offset = 0;
            let mut exit = false;
            loop {
                let mut ram_region_consumed = false;
                let mut pull_next_zone = false;
                let ram_region_sub_size = ram_region.1 - ram_region_offset;
                let zone_sub_size = zone.size as usize - zone_offset;
                let file_offset = zone_offset as u64;
                let region_start = ram_region
                    .0
                    .checked_add(ram_region_offset as u64)
                    .ok_or(Error::GuestAddressOverFlow)?;
                let region_size = if zone_sub_size <= ram_region_sub_size {
                    if zone_sub_size == ram_region_sub_size {
                        ram_region_consumed = true;
                    }
                    ram_region_offset += zone_sub_size;
                    pull_next_zone = true;
                    zone_sub_size
                } else {
                    zone_offset += ram_region_sub_size;
                    ram_region_consumed = true;
                    ram_region_sub_size
                };
                let region = MemoryManager::create_ram_region(
                    &zone.file,
                    file_offset,
                    region_start,
                    region_size,
                    prefault,
                    zone.shared,
                    zone.hugepages,
                    zone.host_numa_node,
                )?;
                // Add region to the list of regions associated with the
                // current memory zone.
                if let Some(memory_zone) = memory_zones.get_mut(&zone.id) {
                    memory_zone.regions.push(region.clone());
                }
                mem_regions.push(region);
                if pull_next_zone {
                    // Get the next zone and reset the offset.
                    zone_offset = 0;
                    if zones.is_empty() {
                        exit = true;
                        break;
                    }
                    zone = zones.remove(0);
                    // Check if zone id already exist. In case it does, throw
                    // an error as we need unique identifiers. Otherwise, add
                    // the new zone id to the list of memory zones.
                    if memory_zones.contains_key(&zone.id) {
                        error!(
                            "Memory zone identifier '{}' found more than once. \
                            It must be unique",
                            zone.id,
                        );
                        return Err(Error::DuplicateZoneId);
                    }
                    memory_zones.insert(zone.id.clone(), MemoryZone::default());
                }
                if ram_region_consumed {
                    break;
                }
            }
            if exit {
                break;
            }
        }
        Ok((mem_regions, memory_zones))
    }
fn create_memory_regions_from_zones ( ram_regions : & [ ( GuestAddress , usize ) ] , zones : & [ MemoryZoneConfig ] , prefault : bool , ) -> Result < ( Vec < Arc < GuestRegionMmap > > , MemoryZones ) , Error > { let mut zones = zones . to_owned ( ) ; let mut mem_regions = Vec :: new ( ) ; let mut zone = zones . remove ( 0 ) ; let mut zone_offset = 0 ; let mut memory_zones = HashMap :: new ( ) ; // Add zone id to the list of memory zones. memory_zones . insert ( zone . id . clone ( ) , MemoryZone :: default ( ) ) ; for ram_region in ram_regions . iter ( ) { let mut ram_region_offset = 0 ; let mut exit = false ; loop { let mut ram_region_consumed = false ; let mut pull_next_zone = false ; let ram_region_sub_size = ram_region . 1 - ram_region_offset ; let zone_sub_size = zone . size as usize - zone_offset ; let file_offset = zone_offset as u64 ; let region_start = ram_region . 0 . checked_add ( ram_region_offset as u64 ) . ok_or ( Error :: GuestAddressOverFlow ) ? ; let region_size = if zone_sub_size <= ram_region_sub_size { if zone_sub_size == ram_region_sub_size { ram_region_consumed = true ; } ram_region_offset += zone_sub_size ; pull_next_zone = true ; zone_sub_size } else { zone_offset += ram_region_sub_size ; ram_region_consumed = true ; ram_region_sub_size } ; let region = MemoryManager :: create_ram_region ( & zone . file , file_offset , region_start , region_size , prefault , zone . shared , zone . hugepages , zone . host_numa_node , ) ? ; // Add region to the list of regions associated with the // current memory zone. if let Some ( memory_zone ) = memory_zones . get_mut ( & zone . id ) { memory_zone . regions . push ( region . clone ( ) ) ; } mem_regions . push ( region ) ; if pull_next_zone { // Get the next zone and reset the offset. zone_offset = 0 ; if zones . is_empty ( ) { exit = true ; break ; } zone = zones . remove ( 0 ) ; // Check if zone id already exist. In case it does, throw // an error as we need unique identifiers. Otherwise, add // the new zone id to the list of memory zones. if memory_zones . contains_key ( & zone . id ) { error ! ( " \
 " zone id ) ; return Err ( Error :: DuplicateZoneId ) ; } memory_zones . insert ( zone . id . clone ( ) , MemoryZone :: default ( ) ) ; } if ram_region_consumed { break ; } } if exit { break ; } } Ok ( ( mem_regions , memory_zones ) ) }
Creates all memory regions based on the available RAM ranges defined
by `ram_regions`, and based on the description of the memory zones.
Creates all memory regions based on the available RAM ranges defined by ` ram_regions ` and based on the description of the memory zones .
ram_regions
&[(GuestAddress, usize)]
zones
&[MemoryZoneConfig]
prefault
bool
ram_regions
&[(GuestAddress, usize)]
zones
&[MemoryZoneConfig]
prefault
bool