16fc066acSJomo use crate::{ 26fc066acSJomo arch::mm::LockedFrameAllocator, 36fc066acSJomo filesystem::vfs::syscall::ModeType, 46fc066acSJomo libs::{ 56fc066acSJomo align::page_align_up, 66fc066acSJomo spinlock::{SpinLock, SpinLockGuard}, 76fc066acSJomo }, 86fc066acSJomo mm::{ 96fc066acSJomo allocator::page_frame::{FrameAllocator, PageFrameCount, PhysPageFrame}, 106fc066acSJomo page::{page_manager_lock_irqsave, Page}, 116fc066acSJomo PhysAddr, 126fc066acSJomo }, 136fc066acSJomo process::{Pid, ProcessManager}, 146fc066acSJomo syscall::user_access::{UserBufferReader, UserBufferWriter}, 156fc066acSJomo time::PosixTimeSpec, 166fc066acSJomo }; 176fc066acSJomo use alloc::vec::Vec; 186fc066acSJomo use core::sync::atomic::{compiler_fence, Ordering}; 196fc066acSJomo use hashbrown::{HashMap, HashSet}; 206fc066acSJomo use ida::IdAllocator; 21*2eab6dd7S曾俊 use log::info; 226fc066acSJomo use num::ToPrimitive; 236fc066acSJomo use system_error::SystemError; 246fc066acSJomo 256fc066acSJomo pub static mut SHM_MANAGER: Option<SpinLock<ShmManager>> = None; 266fc066acSJomo 276fc066acSJomo /// 用于创建新的私有IPC对象 286fc066acSJomo pub const IPC_PRIVATE: ShmKey = ShmKey::new(0); 296fc066acSJomo 306fc066acSJomo /// 初始化SHM_MANAGER 316fc066acSJomo pub fn shm_manager_init() { 32*2eab6dd7S曾俊 info!("shm_manager_init"); 336fc066acSJomo let shm_manager = SpinLock::new(ShmManager::new()); 346fc066acSJomo 356fc066acSJomo compiler_fence(Ordering::SeqCst); 366fc066acSJomo unsafe { SHM_MANAGER = Some(shm_manager) }; 376fc066acSJomo compiler_fence(Ordering::SeqCst); 386fc066acSJomo 39*2eab6dd7S曾俊 info!("shm_manager_init done"); 406fc066acSJomo } 416fc066acSJomo 426fc066acSJomo pub fn shm_manager_lock() -> SpinLockGuard<'static, ShmManager> { 436fc066acSJomo unsafe { SHM_MANAGER.as_ref().unwrap().lock() } 446fc066acSJomo } 456fc066acSJomo 466fc066acSJomo int_like!(ShmId, usize); 476fc066acSJomo int_like!(ShmKey, usize); 486fc066acSJomo 496fc066acSJomo bitflags! { 506fc066acSJomo pub struct ShmFlags:u32{ 516fc066acSJomo const SHM_RDONLY = 0o10000; 526fc066acSJomo const SHM_RND = 0o20000; 536fc066acSJomo const SHM_REMAP = 0o40000; 546fc066acSJomo const SHM_EXEC = 0o100000; 556fc066acSJomo const SHM_HUGETLB = 0o4000; 566fc066acSJomo 576fc066acSJomo const IPC_CREAT = 0o1000; 586fc066acSJomo const IPC_EXCL = 0o2000; 596fc066acSJomo 606fc066acSJomo const SHM_DEST = 0o1000; 616fc066acSJomo const SHM_LOCKED = 0o2000; 626fc066acSJomo } 636fc066acSJomo } 646fc066acSJomo 656fc066acSJomo /// 管理共享内存段信息的操作码 666fc066acSJomo #[derive(Eq, Clone, Copy)] 676fc066acSJomo pub enum ShmCtlCmd { 686fc066acSJomo /// 删除共享内存段 696fc066acSJomo IpcRmid = 0, 706fc066acSJomo /// 设置KernIpcPerm选项 716fc066acSJomo IpcSet = 1, 726fc066acSJomo /// 获取ShmIdDs 736fc066acSJomo IpcStat = 2, 746fc066acSJomo /// 查看ShmMetaData 756fc066acSJomo IpcInfo = 3, 766fc066acSJomo 776fc066acSJomo /// 不允许共享内存段被置换出物理内存 786fc066acSJomo ShmLock = 11, 796fc066acSJomo /// 允许共享内存段被置换出物理内存 806fc066acSJomo ShmUnlock = 12, 816fc066acSJomo /// 查看ShmMetaData 826fc066acSJomo ShmStat = 13, 836fc066acSJomo /// 查看ShmInfo 846fc066acSJomo ShmInfo = 14, 856fc066acSJomo /// 查看ShmMetaData 866fc066acSJomo ShmtStatAny = 15, 876fc066acSJomo 886fc066acSJomo Default, 896fc066acSJomo } 906fc066acSJomo 916fc066acSJomo impl From<usize> for ShmCtlCmd { 926fc066acSJomo fn from(cmd: usize) -> ShmCtlCmd { 936fc066acSJomo match cmd { 946fc066acSJomo 0 => Self::IpcRmid, 956fc066acSJomo 1 => Self::IpcSet, 966fc066acSJomo 2 => Self::IpcStat, 976fc066acSJomo 3 => Self::IpcInfo, 986fc066acSJomo 11 => Self::ShmLock, 996fc066acSJomo 12 => Self::ShmUnlock, 1006fc066acSJomo 13 => Self::ShmStat, 1016fc066acSJomo 14 => Self::ShmInfo, 1026fc066acSJomo 15 => Self::ShmtStatAny, 1036fc066acSJomo _ => Self::Default, 1046fc066acSJomo } 1056fc066acSJomo } 1066fc066acSJomo } 1076fc066acSJomo 1086fc066acSJomo impl PartialEq for ShmCtlCmd { 1096fc066acSJomo fn eq(&self, other: &ShmCtlCmd) -> bool { 1106fc066acSJomo *self as usize == *other as usize 1116fc066acSJomo } 1126fc066acSJomo } 1136fc066acSJomo 1146fc066acSJomo /// 共享内存管理器 1156fc066acSJomo #[derive(Debug)] 1166fc066acSJomo pub struct ShmManager { 1176fc066acSJomo /// ShmId分配器 1186fc066acSJomo id_allocator: IdAllocator, 1196fc066acSJomo /// ShmId映射共享内存信息表 1206fc066acSJomo id2shm: HashMap<ShmId, KernelShm>, 1216fc066acSJomo /// ShmKey映射ShmId表 1226fc066acSJomo key2id: HashMap<ShmKey, ShmId>, 1236fc066acSJomo } 1246fc066acSJomo 1256fc066acSJomo impl ShmManager { 1266fc066acSJomo pub fn new() -> Self { 1276fc066acSJomo ShmManager { 1286fc066acSJomo id_allocator: IdAllocator::new(0, usize::MAX - 1), 1296fc066acSJomo id2shm: HashMap::new(), 1306fc066acSJomo key2id: HashMap::new(), 1316fc066acSJomo } 1326fc066acSJomo } 1336fc066acSJomo 1346fc066acSJomo /// # 添加共享内存段 1356fc066acSJomo /// 1366fc066acSJomo /// ## 参数 1376fc066acSJomo /// 1386fc066acSJomo /// - `key`: 共享内存键值 1396fc066acSJomo /// - `size`: 共享内存大小 1406fc066acSJomo /// - `shmflg`: 共享内存标志 1416fc066acSJomo /// 1426fc066acSJomo /// ## 返回值 1436fc066acSJomo /// 1446fc066acSJomo /// 成功:共享内存id 1456fc066acSJomo /// 失败:对应错误码 1466fc066acSJomo pub fn add( 1476fc066acSJomo &mut self, 1486fc066acSJomo key: ShmKey, 1496fc066acSJomo size: usize, 1506fc066acSJomo shmflg: ShmFlags, 1516fc066acSJomo ) -> Result<usize, SystemError> { 1526fc066acSJomo // 判断共享内存大小是否过小或溢出 1536fc066acSJomo if !(PosixShmMetaInfo::SHMMIN..=PosixShmMetaInfo::SHMMAX).contains(&size) { 1546fc066acSJomo return Err(SystemError::EINVAL); 1556fc066acSJomo } 1566fc066acSJomo 1576fc066acSJomo let id = self.id_allocator.alloc().expect("No more id to allocate."); 1586fc066acSJomo let shm_id = ShmId::new(id); 1596fc066acSJomo 1606fc066acSJomo // 分配共享内存页面 1616fc066acSJomo let page_count = PageFrameCount::from_bytes(page_align_up(size)).unwrap(); 1626fc066acSJomo let phys_page = 1636fc066acSJomo unsafe { LockedFrameAllocator.allocate(page_count) }.ok_or(SystemError::EINVAL)?; 1646fc066acSJomo // 创建共享内存page,并添加到PAGE_MANAGER中 1656fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave(); 1666fc066acSJomo let mut cur_phys = PhysPageFrame::new(phys_page.0); 1676fc066acSJomo for _ in 0..page_count.data() { 1686fc066acSJomo let mut page = Page::new(true); 1696fc066acSJomo page.set_shm_id(shm_id); 1706fc066acSJomo let paddr = cur_phys.phys_address(); 1716fc066acSJomo page_manager_guard.insert(paddr, page); 1726fc066acSJomo cur_phys = cur_phys.next(); 1736fc066acSJomo } 1746fc066acSJomo 1756fc066acSJomo // 创建共享内存信息结构体 1766fc066acSJomo let paddr = phys_page.0; 1776fc066acSJomo let kern_ipc_perm = KernIpcPerm { 1786fc066acSJomo id: shm_id, 1796fc066acSJomo key, 1806fc066acSJomo uid: 0, 1816fc066acSJomo gid: 0, 1826fc066acSJomo _cuid: 0, 1836fc066acSJomo _cgid: 0, 1846fc066acSJomo mode: shmflg & ShmFlags::from_bits_truncate(ModeType::S_IRWXUGO.bits()), 1856fc066acSJomo _seq: 0, 1866fc066acSJomo }; 1876fc066acSJomo let shm_kernel = KernelShm::new(kern_ipc_perm, paddr, size); 1886fc066acSJomo 1896fc066acSJomo // 将key、id及其对应KernelShm添加到表中 1906fc066acSJomo self.id2shm.insert(shm_id, shm_kernel); 1916fc066acSJomo self.key2id.insert(key, shm_id); 1926fc066acSJomo 1936fc066acSJomo return Ok(shm_id.data()); 1946fc066acSJomo } 1956fc066acSJomo 1966fc066acSJomo pub fn contains_key(&self, key: &ShmKey) -> Option<&ShmId> { 1976fc066acSJomo self.key2id.get(key) 1986fc066acSJomo } 1996fc066acSJomo 2006fc066acSJomo pub fn get_mut(&mut self, id: &ShmId) -> Option<&mut KernelShm> { 2016fc066acSJomo self.id2shm.get_mut(id) 2026fc066acSJomo } 2036fc066acSJomo 2046fc066acSJomo pub fn free_key(&mut self, key: &ShmKey) { 2056fc066acSJomo self.key2id.remove(key); 2066fc066acSJomo } 2076fc066acSJomo 2086fc066acSJomo pub fn free_id(&mut self, id: &ShmId) { 2096fc066acSJomo self.id2shm.remove(id); 2106fc066acSJomo self.id_allocator.free(id.0); 2116fc066acSJomo } 2126fc066acSJomo 2136fc066acSJomo pub fn ipc_info(&self, user_buf: *const u8, from_user: bool) -> Result<usize, SystemError> { 2146fc066acSJomo let mut user_buffer_writer = UserBufferWriter::new( 2156fc066acSJomo user_buf as *mut u8, 2166fc066acSJomo core::mem::size_of::<PosixShmMetaInfo>(), 2176fc066acSJomo from_user, 2186fc066acSJomo )?; 2196fc066acSJomo 2206fc066acSJomo let shm_meta_info = PosixShmMetaInfo::new(); 2216fc066acSJomo user_buffer_writer.copy_one_to_user(&shm_meta_info, 0)?; 2226fc066acSJomo 2236fc066acSJomo return Ok(0); 2246fc066acSJomo } 2256fc066acSJomo 2266fc066acSJomo pub fn shm_info(&self, user_buf: *const u8, from_user: bool) -> Result<usize, SystemError> { 2276fc066acSJomo // 已使用id数量 2286fc066acSJomo let used_ids = self.id2shm.len().to_i32().unwrap(); 2296fc066acSJomo // 共享内存总和 2306fc066acSJomo let shm_tot = self.id2shm.iter().fold(0, |acc, (_, kernel_shm)| { 2316fc066acSJomo acc + PageFrameCount::from_bytes(page_align_up(kernel_shm.shm_size)) 2326fc066acSJomo .unwrap() 2336fc066acSJomo .data() 2346fc066acSJomo }); 2356fc066acSJomo let shm_info = PosixShmInfo::new(used_ids, shm_tot, 0, 0, 0, 0); 2366fc066acSJomo 2376fc066acSJomo let mut user_buffer_writer = UserBufferWriter::new( 2386fc066acSJomo user_buf as *mut u8, 2396fc066acSJomo core::mem::size_of::<PosixShmInfo>(), 2406fc066acSJomo from_user, 2416fc066acSJomo )?; 2426fc066acSJomo user_buffer_writer.copy_one_to_user(&shm_info, 0)?; 2436fc066acSJomo 2446fc066acSJomo return Ok(0); 2456fc066acSJomo } 2466fc066acSJomo 2476fc066acSJomo pub fn shm_stat( 2486fc066acSJomo &self, 2496fc066acSJomo id: ShmId, 2506fc066acSJomo cmd: ShmCtlCmd, 2516fc066acSJomo user_buf: *const u8, 2526fc066acSJomo from_user: bool, 2536fc066acSJomo ) -> Result<usize, SystemError> { 2546fc066acSJomo let kernel_shm = self.id2shm.get(&id).ok_or(SystemError::EINVAL)?; 2556fc066acSJomo let key = kernel_shm.kern_ipc_perm.key.data().to_i32().unwrap(); 2566fc066acSJomo let mode = kernel_shm.kern_ipc_perm.mode.bits(); 2576fc066acSJomo 2586fc066acSJomo let shm_perm = PosixIpcPerm::new(key, 0, 0, 0, 0, mode); 2596fc066acSJomo let shm_segsz = kernel_shm.shm_size; 2606fc066acSJomo let shm_atime = kernel_shm.shm_atim.total_nanos(); 2616fc066acSJomo let shm_dtime = kernel_shm.shm_dtim.total_nanos(); 2626fc066acSJomo let shm_ctime = kernel_shm.shm_ctim.total_nanos(); 2636fc066acSJomo let shm_cpid = kernel_shm.shm_cprid.data().to_u32().unwrap(); 2646fc066acSJomo let shm_lpid = kernel_shm.shm_lprid.data().to_u32().unwrap(); 2656fc066acSJomo let shm_map_count = kernel_shm.map_count(); 2666fc066acSJomo let shm_id_ds = PosixShmIdDs { 2676fc066acSJomo shm_perm, 2686fc066acSJomo shm_segsz, 2696fc066acSJomo shm_atime, 2706fc066acSJomo shm_dtime, 2716fc066acSJomo shm_ctime, 2726fc066acSJomo shm_cpid, 2736fc066acSJomo shm_lpid, 2746fc066acSJomo shm_map_count, 2756fc066acSJomo _unused1: 0, 2766fc066acSJomo _unused2: 0, 2776fc066acSJomo }; 2786fc066acSJomo 2796fc066acSJomo let mut user_buffer_writer = UserBufferWriter::new( 2806fc066acSJomo user_buf as *mut u8, 2816fc066acSJomo core::mem::size_of::<PosixShmIdDs>(), 2826fc066acSJomo from_user, 2836fc066acSJomo )?; 2846fc066acSJomo user_buffer_writer.copy_one_to_user(&shm_id_ds, 0)?; 2856fc066acSJomo 2866fc066acSJomo let r: usize = if cmd == ShmCtlCmd::IpcStat { 2876fc066acSJomo 0 2886fc066acSJomo } else { 2896fc066acSJomo id.data() 2906fc066acSJomo }; 2916fc066acSJomo 2926fc066acSJomo return Ok(r); 2936fc066acSJomo } 2946fc066acSJomo 2956fc066acSJomo pub fn ipc_set( 2966fc066acSJomo &mut self, 2976fc066acSJomo id: ShmId, 2986fc066acSJomo user_buf: *const u8, 2996fc066acSJomo from_user: bool, 3006fc066acSJomo ) -> Result<usize, SystemError> { 3016fc066acSJomo let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?; 3026fc066acSJomo 3036fc066acSJomo let user_buffer_reader = 3046fc066acSJomo UserBufferReader::new(user_buf, core::mem::size_of::<PosixShmIdDs>(), from_user)?; 3056fc066acSJomo let mut shm_id_ds = PosixShmIdDs::default(); 3066fc066acSJomo user_buffer_reader.copy_one_from_user(&mut shm_id_ds, 0)?; 3076fc066acSJomo 3086fc066acSJomo kernel_shm.copy_from(shm_id_ds); 3096fc066acSJomo 3106fc066acSJomo return Ok(0); 3116fc066acSJomo } 3126fc066acSJomo 3136fc066acSJomo pub fn ipc_rmid(&mut self, id: ShmId) -> Result<usize, SystemError> { 3146fc066acSJomo let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?; 3156fc066acSJomo kernel_shm.set_mode(ShmFlags::SHM_DEST, true); 3166fc066acSJomo 3176fc066acSJomo let mut cur_phys = PhysPageFrame::new(kernel_shm.shm_start_paddr); 3186fc066acSJomo let count = PageFrameCount::from_bytes(page_align_up(kernel_shm.shm_size)).unwrap(); 3196fc066acSJomo let key = kernel_shm.kern_ipc_perm.key; 3206fc066acSJomo let id = kernel_shm.kern_ipc_perm.id; 3216fc066acSJomo let map_count = kernel_shm.map_count(); 3226fc066acSJomo 3236fc066acSJomo let mut page_manager_guard = page_manager_lock_irqsave(); 3246fc066acSJomo if map_count > 0 { 3256fc066acSJomo // 设置共享内存物理页当映射计数等于0时可被回收 3266fc066acSJomo for _ in 0..count.data() { 3276fc066acSJomo let page = page_manager_guard.get_mut(&cur_phys.phys_address()); 3286fc066acSJomo page.set_dealloc_when_zero(true); 3296fc066acSJomo 3306fc066acSJomo cur_phys = cur_phys.next(); 3316fc066acSJomo } 3326fc066acSJomo 3336fc066acSJomo // 释放key,不让后续进程连接 3346fc066acSJomo self.free_key(&key); 3356fc066acSJomo } else { 3366fc066acSJomo // 释放共享内存物理页 3376fc066acSJomo for _ in 0..count.data() { 3386fc066acSJomo let paddr = cur_phys.phys_address(); 3396fc066acSJomo unsafe { 3406fc066acSJomo LockedFrameAllocator.free(paddr, PageFrameCount::new(1)); 3416fc066acSJomo } 3426fc066acSJomo // 将已回收的物理页面对应的Page从PAGE_MANAGER中删去 3436fc066acSJomo page_manager_guard.remove_page(&paddr); 3446fc066acSJomo cur_phys = cur_phys.next(); 3456fc066acSJomo } 3466fc066acSJomo 3476fc066acSJomo // 释放key和id 3486fc066acSJomo self.free_id(&id); 3496fc066acSJomo self.free_key(&key) 3506fc066acSJomo } 3516fc066acSJomo 3526fc066acSJomo return Ok(0); 3536fc066acSJomo } 3546fc066acSJomo 3556fc066acSJomo pub fn shm_lock(&mut self, id: ShmId) -> Result<usize, SystemError> { 3566fc066acSJomo let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?; 3576fc066acSJomo kernel_shm.set_mode(ShmFlags::SHM_LOCKED, true); 3586fc066acSJomo 3596fc066acSJomo return Ok(0); 3606fc066acSJomo } 3616fc066acSJomo 3626fc066acSJomo pub fn shm_unlock(&mut self, id: ShmId) -> Result<usize, SystemError> { 3636fc066acSJomo let kernel_shm = self.id2shm.get_mut(&id).ok_or(SystemError::EINVAL)?; 3646fc066acSJomo kernel_shm.set_mode(ShmFlags::SHM_LOCKED, false); 3656fc066acSJomo 3666fc066acSJomo return Ok(0); 3676fc066acSJomo } 3686fc066acSJomo } 3696fc066acSJomo /// 共享内存信息 3706fc066acSJomo #[derive(Debug)] 3716fc066acSJomo pub struct KernelShm { 3726fc066acSJomo /// 权限信息 3736fc066acSJomo kern_ipc_perm: KernIpcPerm, 3746fc066acSJomo /// 共享内存起始物理地址 3756fc066acSJomo shm_start_paddr: PhysAddr, 3766fc066acSJomo /// 共享内存大小(bytes),注意是用户指定的大小(未经过页面对齐) 3776fc066acSJomo shm_size: usize, 3786fc066acSJomo /// 最后一次连接的时间 3796fc066acSJomo shm_atim: PosixTimeSpec, 3806fc066acSJomo /// 最后一次断开连接的时间 3816fc066acSJomo shm_dtim: PosixTimeSpec, 3826fc066acSJomo /// 最后一次更改信息的时间 3836fc066acSJomo shm_ctim: PosixTimeSpec, 3846fc066acSJomo /// 创建者进程id 3856fc066acSJomo shm_cprid: Pid, 3866fc066acSJomo /// 最后操作者进程id 3876fc066acSJomo shm_lprid: Pid, 3886fc066acSJomo } 3896fc066acSJomo 3906fc066acSJomo impl KernelShm { 3916fc066acSJomo pub fn new(kern_ipc_perm: KernIpcPerm, shm_start_paddr: PhysAddr, shm_size: usize) -> Self { 3926fc066acSJomo let shm_cprid = ProcessManager::current_pid(); 3936fc066acSJomo KernelShm { 3946fc066acSJomo kern_ipc_perm, 3956fc066acSJomo shm_start_paddr, 3966fc066acSJomo shm_size, 3976fc066acSJomo shm_atim: PosixTimeSpec::new(0, 0), 3986fc066acSJomo shm_dtim: PosixTimeSpec::new(0, 0), 3996fc066acSJomo shm_ctim: PosixTimeSpec::now(), 4006fc066acSJomo shm_cprid, 4016fc066acSJomo shm_lprid: shm_cprid, 4026fc066acSJomo } 4036fc066acSJomo } 4046fc066acSJomo 4056fc066acSJomo pub fn start_paddr(&self) -> PhysAddr { 4066fc066acSJomo self.shm_start_paddr 4076fc066acSJomo } 4086fc066acSJomo 4096fc066acSJomo pub fn size(&self) -> usize { 4106fc066acSJomo self.shm_size 4116fc066acSJomo } 4126fc066acSJomo 4136fc066acSJomo /// 更新最后连接时间 4146fc066acSJomo pub fn update_atim(&mut self) { 4156fc066acSJomo // 更新最后一次连接时间 4166fc066acSJomo self.shm_atim = PosixTimeSpec::now(); 4176fc066acSJomo 4186fc066acSJomo // 更新最后操作当前共享内存的进程ID 4196fc066acSJomo self.shm_lprid = ProcessManager::current_pid(); 4206fc066acSJomo } 4216fc066acSJomo 4226fc066acSJomo /// 更新最后断开连接时间 4236fc066acSJomo pub fn update_dtim(&mut self) { 4246fc066acSJomo // 更新最后一次断开连接时间 4256fc066acSJomo self.shm_dtim = PosixTimeSpec::now(); 4266fc066acSJomo 4276fc066acSJomo // 更新最后操作当前共享内存的进程ID 4286fc066acSJomo self.shm_lprid = ProcessManager::current_pid(); 4296fc066acSJomo } 4306fc066acSJomo 4316fc066acSJomo /// 更新最后一次修改信息的时间 4326fc066acSJomo pub fn update_ctim(&mut self) { 4336fc066acSJomo // 更新最后一次修改信息的时间 4346fc066acSJomo self.shm_ctim = PosixTimeSpec::now(); 4356fc066acSJomo } 4366fc066acSJomo 4376fc066acSJomo /// 共享内存段的映射计数(有多少个不同的VMA映射) 4386fc066acSJomo pub fn map_count(&self) -> usize { 4396fc066acSJomo let page_manager_guard = page_manager_lock_irqsave(); 4406fc066acSJomo let mut id_set: HashSet<usize> = HashSet::new(); 4416fc066acSJomo let mut cur_phys = PhysPageFrame::new(self.shm_start_paddr); 4426fc066acSJomo let page_count = PageFrameCount::from_bytes(page_align_up(self.shm_size)).unwrap(); 4436fc066acSJomo 4446fc066acSJomo for _ in 0..page_count.data() { 4456fc066acSJomo let page = page_manager_guard.get(&cur_phys.phys_address()).unwrap(); 4466fc066acSJomo id_set.extend( 4476fc066acSJomo page.anon_vma() 4486fc066acSJomo .iter() 4496fc066acSJomo .map(|vma| vma.id()) 4506fc066acSJomo .collect::<Vec<_>>(), 4516fc066acSJomo ); 4526fc066acSJomo 4536fc066acSJomo cur_phys = cur_phys.next(); 4546fc066acSJomo } 4556fc066acSJomo 4566fc066acSJomo // 由于LockedVMA的id是独一无二的,因此有多少个不同的id,就代表着有多少个不同的VMA映射到共享内存段 4576fc066acSJomo return id_set.len(); 4586fc066acSJomo } 4596fc066acSJomo 4606fc066acSJomo pub fn copy_from(&mut self, shm_id_ds: PosixShmIdDs) { 4616fc066acSJomo self.kern_ipc_perm.uid = shm_id_ds.uid() as usize; 4626fc066acSJomo self.kern_ipc_perm.gid = shm_id_ds.gid() as usize; 4636fc066acSJomo self.kern_ipc_perm.mode = ShmFlags::from_bits_truncate(shm_id_ds.mode()); 4646fc066acSJomo self.update_ctim(); 4656fc066acSJomo } 4666fc066acSJomo 4676fc066acSJomo pub fn set_mode(&mut self, shmflg: ShmFlags, set: bool) { 4686fc066acSJomo if set { 4696fc066acSJomo self.kern_ipc_perm.mode.insert(shmflg); 4706fc066acSJomo } else { 4716fc066acSJomo self.kern_ipc_perm.mode.remove(shmflg); 4726fc066acSJomo } 4736fc066acSJomo 4746fc066acSJomo self.update_ctim(); 4756fc066acSJomo } 4766fc066acSJomo } 4776fc066acSJomo 4786fc066acSJomo /// 共享内存权限信息 4796fc066acSJomo #[derive(Debug)] 4806fc066acSJomo pub struct KernIpcPerm { 4816fc066acSJomo /// 共享内存id 4826fc066acSJomo id: ShmId, 4836fc066acSJomo /// 共享内存键值,由创建共享内存用户指定 4846fc066acSJomo key: ShmKey, 4856fc066acSJomo /// 共享内存拥有者用户id 4866fc066acSJomo uid: usize, 4876fc066acSJomo /// 共享内存拥有者所在组id 4886fc066acSJomo gid: usize, 4896fc066acSJomo /// 共享内存创建者用户id 4906fc066acSJomo _cuid: usize, 4916fc066acSJomo /// 共享内存创建者所在组id 4926fc066acSJomo _cgid: usize, 4936fc066acSJomo /// 共享内存区权限模式 4946fc066acSJomo mode: ShmFlags, 4956fc066acSJomo _seq: usize, 4966fc066acSJomo } 4976fc066acSJomo 4986fc066acSJomo /// 共享内存元信息,符合POSIX标准 4996fc066acSJomo #[repr(C)] 5006fc066acSJomo #[derive(Debug, Clone, Copy)] 5016fc066acSJomo pub struct PosixShmMetaInfo { 5026fc066acSJomo /// 最大共享内存段的大小(bytes) 5036fc066acSJomo shmmax: usize, 5046fc066acSJomo /// 最小共享内存段的大小(bytes) 5056fc066acSJomo shmmin: usize, 5066fc066acSJomo /// 最大共享内存标识符数量 5076fc066acSJomo shmmni: usize, 5086fc066acSJomo /// 单个进程可以拥有的最大共享内存段的数量,和最大共享内存标识符数量相同 5096fc066acSJomo shmseg: usize, 5106fc066acSJomo /// 所有共享内存段总共可以使用的最大内存量(pages) 5116fc066acSJomo shmall: usize, 5126fc066acSJomo _unused1: usize, 5136fc066acSJomo _unused2: usize, 5146fc066acSJomo _unused3: usize, 5156fc066acSJomo _unused4: usize, 5166fc066acSJomo } 5176fc066acSJomo 5186fc066acSJomo impl PosixShmMetaInfo { 5196fc066acSJomo /// 最小共享内存段的大小(bytes) 5206fc066acSJomo pub const SHMMIN: usize = 1; 5216fc066acSJomo /// 最大共享内存标识符数量 5226fc066acSJomo pub const SHMMNI: usize = 4096; 5236fc066acSJomo /// 最大共享内存段的大小(bytes) 5246fc066acSJomo pub const SHMMAX: usize = usize::MAX - (1 << 24); 5256fc066acSJomo /// 所有共享内存段总共可以使用的最大内存量(pages) 5266fc066acSJomo pub const SHMALL: usize = usize::MAX - (1 << 24); 5276fc066acSJomo /// 单个进程可以拥有的最大共享内存段的数量,和最大共享内存标识符数量相同 5286fc066acSJomo pub const SHMSEG: usize = 4096; 5296fc066acSJomo 5306fc066acSJomo pub fn new() -> Self { 5316fc066acSJomo PosixShmMetaInfo { 5326fc066acSJomo shmmax: Self::SHMMAX, 5336fc066acSJomo shmmin: Self::SHMMIN, 5346fc066acSJomo shmmni: Self::SHMMNI, 5356fc066acSJomo shmseg: Self::SHMSEG, 5366fc066acSJomo shmall: Self::SHMALL, 5376fc066acSJomo _unused1: 0, 5386fc066acSJomo _unused2: 0, 5396fc066acSJomo _unused3: 0, 5406fc066acSJomo _unused4: 0, 5416fc066acSJomo } 5426fc066acSJomo } 5436fc066acSJomo } 5446fc066acSJomo 5456fc066acSJomo /// 共享内存信息,符合POSIX标准 5466fc066acSJomo #[repr(C)] 5476fc066acSJomo #[derive(Clone, Copy)] 5486fc066acSJomo pub struct PosixShmInfo { 5496fc066acSJomo /// 已使用id数 5506fc066acSJomo used_ids: i32, 5516fc066acSJomo /// 共享内存总量(pages) 5526fc066acSJomo shm_tot: usize, 5536fc066acSJomo /// 保留在内存中的共享内存大小 5546fc066acSJomo shm_rss: usize, 5556fc066acSJomo /// 被置换出的共享内存大小 5566fc066acSJomo shm_swp: usize, 5576fc066acSJomo /// 尝试置换次数 5586fc066acSJomo swap_attempts: usize, 5596fc066acSJomo /// 成功置换次数 5606fc066acSJomo swap_successes: usize, 5616fc066acSJomo } 5626fc066acSJomo 5636fc066acSJomo impl PosixShmInfo { 5646fc066acSJomo pub fn new( 5656fc066acSJomo used_ids: i32, 5666fc066acSJomo shm_tot: usize, 5676fc066acSJomo shm_rss: usize, 5686fc066acSJomo shm_swp: usize, 5696fc066acSJomo swap_attempts: usize, 5706fc066acSJomo swap_successes: usize, 5716fc066acSJomo ) -> Self { 5726fc066acSJomo PosixShmInfo { 5736fc066acSJomo used_ids, 5746fc066acSJomo shm_tot, 5756fc066acSJomo shm_rss, 5766fc066acSJomo shm_swp, 5776fc066acSJomo swap_attempts, 5786fc066acSJomo swap_successes, 5796fc066acSJomo } 5806fc066acSJomo } 5816fc066acSJomo } 5826fc066acSJomo 5836fc066acSJomo /// 共享内存段属性信息,符合POSIX标准 5846fc066acSJomo #[repr(C)] 5856fc066acSJomo #[derive(Debug, Clone, Copy, Default)] 5866fc066acSJomo pub struct PosixShmIdDs { 5876fc066acSJomo /// 共享内存段权限 5886fc066acSJomo shm_perm: PosixIpcPerm, 5896fc066acSJomo /// 共享内存大小(bytes) 5906fc066acSJomo shm_segsz: usize, 5916fc066acSJomo /// 最后一次连接的时间 5926fc066acSJomo shm_atime: i64, 5936fc066acSJomo /// 最后一次断开连接的时间 5946fc066acSJomo shm_dtime: i64, 5956fc066acSJomo /// 最后一次更改信息的时间 5966fc066acSJomo shm_ctime: i64, 5976fc066acSJomo /// 创建者进程id 5986fc066acSJomo shm_cpid: u32, 5996fc066acSJomo /// 最后操作者进程id 6006fc066acSJomo shm_lpid: u32, 6016fc066acSJomo /// 链接数 6026fc066acSJomo shm_map_count: usize, 6036fc066acSJomo _unused1: usize, 6046fc066acSJomo _unused2: usize, 6056fc066acSJomo } 6066fc066acSJomo 6076fc066acSJomo impl PosixShmIdDs { 6086fc066acSJomo pub fn uid(&self) -> u32 { 6096fc066acSJomo self.shm_perm.uid 6106fc066acSJomo } 6116fc066acSJomo 6126fc066acSJomo pub fn gid(&self) -> u32 { 6136fc066acSJomo self.shm_perm.gid 6146fc066acSJomo } 6156fc066acSJomo 6166fc066acSJomo pub fn mode(&self) -> u32 { 6176fc066acSJomo self.shm_perm.mode 6186fc066acSJomo } 6196fc066acSJomo } 6206fc066acSJomo 6216fc066acSJomo /// 共享内存段权限,符合POSIX标准 6226fc066acSJomo #[repr(C)] 6236fc066acSJomo #[derive(Debug, Clone, Copy, Default)] 6246fc066acSJomo pub struct PosixIpcPerm { 6256fc066acSJomo /// IPC对象键值 6266fc066acSJomo key: i32, 6276fc066acSJomo /// 当前用户id 6286fc066acSJomo uid: u32, 6296fc066acSJomo /// 当前用户组id 6306fc066acSJomo gid: u32, 6316fc066acSJomo /// 创建者用户id 6326fc066acSJomo cuid: u32, 6336fc066acSJomo /// 创建者组id 6346fc066acSJomo cgid: u32, 6356fc066acSJomo /// 权限 6366fc066acSJomo mode: u32, 6376fc066acSJomo /// 序列号 6386fc066acSJomo seq: i32, 6396fc066acSJomo _pad1: i32, 6406fc066acSJomo _unused1: usize, 6416fc066acSJomo _unused2: usize, 6426fc066acSJomo } 6436fc066acSJomo 6446fc066acSJomo impl PosixIpcPerm { 6456fc066acSJomo pub fn new(key: i32, uid: u32, gid: u32, cuid: u32, cgid: u32, mode: u32) -> Self { 6466fc066acSJomo PosixIpcPerm { 6476fc066acSJomo key, 6486fc066acSJomo uid, 6496fc066acSJomo gid, 6506fc066acSJomo cuid, 6516fc066acSJomo cgid, 6526fc066acSJomo mode, 6536fc066acSJomo seq: 0, 6546fc066acSJomo _pad1: 0, 6556fc066acSJomo _unused1: 0, 6566fc066acSJomo _unused2: 0, 6576fc066acSJomo } 6586fc066acSJomo } 6596fc066acSJomo } 660