Creates a mapping specified by the uid and size
(unique_id: &str, map_size: usize)
| 81 | |
| 82 | /// Creates a mapping specified by the uid and size |
| 83 | pub fn create_mapping(unique_id: &str, map_size: usize) -> Result<MapData, ShmemError> { |
| 84 | //Create shared memory file descriptor |
| 85 | debug!("Creating persistent mapping at {}", unique_id); |
| 86 | let shmem_fd = match shm_open( |
| 87 | unique_id, //Unique name that usualy pops up in /dev/shm/ |
| 88 | OFlag::O_CREAT | OFlag::O_EXCL | OFlag::O_RDWR, //create exclusively (error if collision) and read/write to allow resize |
| 89 | Mode::S_IRUSR | Mode::S_IWUSR, //Permission allow user+rw |
| 90 | ) { |
| 91 | Ok(v) => { |
| 92 | trace!( |
| 93 | "shm_open({}, {:X}, {:X}) == {}", |
| 94 | unique_id, |
| 95 | OFlag::O_CREAT | OFlag::O_EXCL | OFlag::O_RDWR, |
| 96 | Mode::S_IRUSR | Mode::S_IWUSR, |
| 97 | v |
| 98 | ); |
| 99 | v |
| 100 | } |
| 101 | Err(nix::Error::EEXIST) => return Err(ShmemError::MappingIdExists), |
| 102 | Err(e) => return Err(ShmemError::MapCreateFailed(e as u32)), |
| 103 | }; |
| 104 | |
| 105 | let mut new_map: MapData = MapData { |
| 106 | owner: true, |
| 107 | unique_id: String::from(unique_id), |
| 108 | map_fd: shmem_fd, |
| 109 | map_size, |
| 110 | map_ptr: null_mut(), |
| 111 | }; |
| 112 | |
| 113 | //Enlarge the memory descriptor file size to the requested map size |
| 114 | debug!("Creating memory mapping"); |
| 115 | trace!("ftruncate({}, {})", new_map.map_fd, new_map.map_size); |
| 116 | match ftruncate(new_map.map_fd, new_map.map_size as _) { |
| 117 | Ok(_) => {} |
| 118 | Err(e) => return Err(ShmemError::UnknownOsError(e as u32)), |
| 119 | }; |
| 120 | |
| 121 | //Put the mapping in our address space |
| 122 | debug!("Loading mapping into address space"); |
| 123 | new_map.map_ptr = match unsafe { |
| 124 | mmap( |
| 125 | null_mut(), //Desired addr |
| 126 | new_map.map_size, //size of mapping |
| 127 | ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, //Permissions on pages |
| 128 | MapFlags::MAP_SHARED, //What kind of mapping |
| 129 | new_map.map_fd, //fd |
| 130 | 0, //Offset into fd |
| 131 | ) |
| 132 | } { |
| 133 | Ok(v) => { |
| 134 | trace!( |
| 135 | "mmap(NULL, {}, {:X}, {:X}, {}, 0) == {:p}", |
| 136 | new_map.map_size, |
| 137 | ProtFlags::PROT_READ | ProtFlags::PROT_WRITE, |
| 138 | MapFlags::MAP_SHARED, |
| 139 | new_map.map_fd, |
| 140 | v |