xref: /DragonOS/kernel/src/filesystem/procfs/mod.rs (revision 02343d0b5b47c07e7f4ec3818940795b1009fae1)
1 use core::intrinsics::size_of;
2 
3 use alloc::{
4     borrow::ToOwned,
5     collections::BTreeMap,
6     format,
7     string::String,
8     sync::{Arc, Weak},
9     vec::Vec,
10 };
11 use system_error::SystemError;
12 
13 use crate::{
14     arch::mm::LockedFrameAllocator,
15     driver::base::device::device_number::DeviceNumber,
16     filesystem::vfs::{
17         core::{generate_inode_id, ROOT_INODE},
18         FileType,
19     },
20     kerror, kinfo,
21     libs::{
22         once::Once,
23         spinlock::{SpinLock, SpinLockGuard},
24     },
25     mm::allocator::page_frame::FrameAllocator,
26     process::{Pid, ProcessManager},
27     time::TimeSpec,
28 };
29 
30 use super::vfs::{
31     file::{FileMode, FilePrivateData},
32     syscall::ModeType,
33     FileSystem, FsInfo, IndexNode, InodeId, Metadata,
34 };
35 
36 /// @brief 进程文件类型
37 /// @usage 用于定义进程文件夹下的各类文件类型
38 #[derive(Debug)]
39 #[repr(u8)]
40 pub enum ProcFileType {
41     ///展示进程状态信息
42     ProcStatus = 0,
43     /// meminfo
44     ProcMeminfo = 1,
45     //todo: 其他文件类型
46     ///默认文件类型
47     Default,
48 }
49 
50 impl From<u8> for ProcFileType {
51     fn from(value: u8) -> Self {
52         match value {
53             0 => ProcFileType::ProcStatus,
54             1 => ProcFileType::ProcMeminfo,
55             _ => ProcFileType::Default,
56         }
57     }
58 }
59 /// @brief 节点私有信息结构体
60 /// @usage 用于传入各类文件所需的信息
61 #[derive(Debug)]
62 pub struct InodeInfo {
63     ///进程的pid
64     pid: Pid,
65     ///文件类型
66     ftype: ProcFileType,
67     //其他需要传入的信息在此定义
68 }
69 
70 /// @brief procfs的inode名称的最大长度
71 const PROCFS_MAX_NAMELEN: usize = 64;
72 
73 /// @brief procfs文件系统的Inode结构体
74 #[derive(Debug)]
75 pub struct LockedProcFSInode(SpinLock<ProcFSInode>);
76 
77 /// @brief procfs文件系统结构体
78 #[derive(Debug)]
79 pub struct ProcFS {
80     /// procfs的root inode
81     root_inode: Arc<LockedProcFSInode>,
82 }
83 
84 #[derive(Debug, Clone)]
85 pub struct ProcfsFilePrivateData {
86     data: Vec<u8>,
87 }
88 
89 impl ProcfsFilePrivateData {
90     pub fn new() -> Self {
91         return ProcfsFilePrivateData { data: Vec::new() };
92     }
93 }
94 
95 /// @brief procfs文件系统的Inode结构体(不包含锁)
96 #[derive(Debug)]
97 pub struct ProcFSInode {
98     /// 指向父Inode的弱引用
99     parent: Weak<LockedProcFSInode>,
100     /// 指向自身的弱引用
101     self_ref: Weak<LockedProcFSInode>,
102     /// 子Inode的B树
103     children: BTreeMap<String, Arc<LockedProcFSInode>>,
104     /// 当前inode的数据部分
105     data: Vec<u8>,
106     /// 当前inode的元数据
107     metadata: Metadata,
108     /// 指向inode所在的文件系统对象的指针
109     fs: Weak<ProcFS>,
110     /// 储存私有信息
111     fdata: InodeInfo,
112 }
113 
114 /// 对ProcFSInode实现获取各类文件信息的函数
115 impl ProcFSInode {
116     /// @brief 去除Vec中所有的\0,并在结尾添加\0
117     #[inline]
118     fn trim_string(&self, data: &mut Vec<u8>) {
119         data.retain(|x| *x != 0);
120 
121         data.push(0);
122     }
123     // todo:其他数据获取函数实现
124 
125     /// @brief 打开status文件
126     ///
127     fn open_status(&self, pdata: &mut ProcfsFilePrivateData) -> Result<i64, SystemError> {
128         // 获取该pid对应的pcb结构体
129         let pid = self.fdata.pid;
130         let pcb = ProcessManager::find(pid);
131         let pcb = if pcb.is_none() {
132             kerror!(
133                 "ProcFS: Cannot find pcb for pid {:?} when opening its 'status' file.",
134                 pid
135             );
136             return Err(SystemError::ESRCH);
137         } else {
138             pcb.unwrap()
139         };
140         // 传入数据
141         let pdata: &mut Vec<u8> = &mut pdata.data;
142 
143         pdata.append(
144             &mut format!("Name:\t{}", pcb.basic().name())
145                 .as_bytes()
146                 .to_owned(),
147         );
148 
149         let sched_info_guard = pcb.sched_info();
150         let state = sched_info_guard.inner_lock_read_irqsave().state();
151         let cpu_id = sched_info_guard
152             .on_cpu()
153             .map(|cpu| cpu as i32)
154             .unwrap_or(-1);
155 
156         let priority = sched_info_guard.priority();
157         let vrtime = sched_info_guard.virtual_runtime();
158 
159         pdata.append(&mut format!("\nState:\t{:?}", state).as_bytes().to_owned());
160         pdata.append(
161             &mut format!("\nPid:\t{}", pcb.pid().into())
162                 .as_bytes()
163                 .to_owned(),
164         );
165         pdata.append(
166             &mut format!("\nPpid:\t{}", pcb.basic().ppid().into())
167                 .as_bytes()
168                 .to_owned(),
169         );
170         pdata.append(&mut format!("\ncpu_id:\t{}", cpu_id).as_bytes().to_owned());
171         pdata.append(
172             &mut format!("\npriority:\t{}", priority.data())
173                 .as_bytes()
174                 .to_owned(),
175         );
176         pdata.append(
177             &mut format!("\npreempt:\t{}", pcb.preempt_count())
178                 .as_bytes()
179                 .to_owned(),
180         );
181         pdata.append(&mut format!("\nvrtime:\t{}", vrtime).as_bytes().to_owned());
182 
183         if let Some(user_vm) = pcb.basic().user_vm() {
184             let address_space_guard = user_vm.read();
185             // todo: 当前进程运行过程中占用内存的峰值
186             let hiwater_vm: u64 = 0;
187             // 进程代码段的大小
188             let text = (address_space_guard.end_code - address_space_guard.start_code) / 1024;
189             // 进程数据段的大小
190             let data = (address_space_guard.end_data - address_space_guard.start_data) / 1024;
191             drop(address_space_guard);
192             pdata.append(
193                 &mut format!("\nVmPeak:\t{} kB", hiwater_vm)
194                     .as_bytes()
195                     .to_owned(),
196             );
197             pdata.append(&mut format!("\nVmData:\t{} kB", data).as_bytes().to_owned());
198             pdata.append(&mut format!("\nVmExe:\t{} kB", text).as_bytes().to_owned());
199         }
200 
201         pdata.append(
202             &mut format!("\nflags: {:?}\n", pcb.flags().clone())
203                 .as_bytes()
204                 .to_owned(),
205         );
206 
207         // 去除多余的\0
208         self.trim_string(pdata);
209 
210         return Ok((pdata.len() * size_of::<u8>()) as i64);
211     }
212 
213     /// 打开 meminfo 文件
214     fn open_meminfo(&self, pdata: &mut ProcfsFilePrivateData) -> Result<i64, SystemError> {
215         // 获取内存信息
216         let usage = unsafe { LockedFrameAllocator.usage() };
217 
218         // 传入数据
219         let data: &mut Vec<u8> = &mut pdata.data;
220 
221         data.append(
222             &mut format!("MemTotal:\t{} kB\n", usage.total().bytes() >> 10)
223                 .as_bytes()
224                 .to_owned(),
225         );
226 
227         data.append(
228             &mut format!("MemFree:\t{} kB\n", usage.free().bytes() >> 10)
229                 .as_bytes()
230                 .to_owned(),
231         );
232 
233         // 去除多余的\0
234         self.trim_string(data);
235 
236         return Ok((data.len() * size_of::<u8>()) as i64);
237     }
238 
239     /// proc文件系统读取函数
240     fn proc_read(
241         &self,
242         offset: usize,
243         len: usize,
244         buf: &mut [u8],
245         _pdata: &mut ProcfsFilePrivateData,
246     ) -> Result<usize, SystemError> {
247         let start = _pdata.data.len().min(offset);
248         let end = _pdata.data.len().min(offset + len);
249 
250         // buffer空间不足
251         if buf.len() < (end - start) {
252             return Err(SystemError::ENOBUFS);
253         }
254 
255         // 拷贝数据
256         let src = &_pdata.data[start..end];
257         buf[0..src.len()].copy_from_slice(src);
258         return Ok(src.len());
259     }
260 }
261 
262 impl FileSystem for ProcFS {
263     fn root_inode(&self) -> Arc<dyn super::vfs::IndexNode> {
264         return self.root_inode.clone();
265     }
266 
267     fn info(&self) -> FsInfo {
268         return FsInfo {
269             blk_dev_id: 0,
270             max_name_len: PROCFS_MAX_NAMELEN,
271         };
272     }
273 
274     fn as_any_ref(&self) -> &dyn core::any::Any {
275         self
276     }
277 }
278 
279 impl ProcFS {
280     pub fn new() -> Arc<Self> {
281         // 初始化root inode
282         let root: Arc<LockedProcFSInode> =
283             Arc::new(LockedProcFSInode(SpinLock::new(ProcFSInode {
284                 parent: Weak::default(),
285                 self_ref: Weak::default(),
286                 children: BTreeMap::new(),
287                 data: Vec::new(),
288                 metadata: Metadata {
289                     dev_id: 0,
290                     inode_id: generate_inode_id(),
291                     size: 0,
292                     blk_size: 0,
293                     blocks: 0,
294                     atime: TimeSpec::default(),
295                     mtime: TimeSpec::default(),
296                     ctime: TimeSpec::default(),
297                     file_type: FileType::Dir,
298                     mode: ModeType::from_bits_truncate(0o555),
299                     nlinks: 1,
300                     uid: 0,
301                     gid: 0,
302                     raw_dev: DeviceNumber::default(),
303                 },
304                 fs: Weak::default(),
305                 fdata: InodeInfo {
306                     pid: Pid::new(0),
307                     ftype: ProcFileType::Default,
308                 },
309             })));
310 
311         let result: Arc<ProcFS> = Arc::new(ProcFS { root_inode: root });
312 
313         // 对root inode加锁,并继续完成初始化工作
314         let mut root_guard: SpinLockGuard<ProcFSInode> = result.root_inode.0.lock();
315         root_guard.parent = Arc::downgrade(&result.root_inode);
316         root_guard.self_ref = Arc::downgrade(&result.root_inode);
317         root_guard.fs = Arc::downgrade(&result);
318         // 释放锁
319         drop(root_guard);
320 
321         // 创建meminfo文件
322         let inode = result.root_inode();
323         let binding = inode.create(
324             "meminfo",
325             FileType::File,
326             ModeType::from_bits_truncate(0o444),
327         );
328         if let Ok(meminfo) = binding {
329             let meminfo_file = meminfo
330                 .as_any_ref()
331                 .downcast_ref::<LockedProcFSInode>()
332                 .unwrap();
333             meminfo_file.0.lock().fdata.pid = Pid::new(0);
334             meminfo_file.0.lock().fdata.ftype = ProcFileType::ProcMeminfo;
335         } else {
336             panic!("create meminfo error");
337         }
338 
339         return result;
340     }
341 
342     /// @brief 进程注册函数
343     /// @usage 在进程中调用并创建进程对应文件
344     pub fn register_pid(&self, pid: Pid) -> Result<(), SystemError> {
345         // 获取当前inode
346         let inode: Arc<dyn IndexNode> = self.root_inode();
347         // 创建对应进程文件夹
348         let pid_dir: Arc<dyn IndexNode> = inode.create(
349             &pid.to_string(),
350             FileType::Dir,
351             ModeType::from_bits_truncate(0o555),
352         )?;
353         // 创建相关文件
354         // status文件
355         let binding: Arc<dyn IndexNode> = pid_dir.create(
356             "status",
357             FileType::File,
358             ModeType::from_bits_truncate(0o444),
359         )?;
360         let status_file: &LockedProcFSInode = binding
361             .as_any_ref()
362             .downcast_ref::<LockedProcFSInode>()
363             .unwrap();
364         status_file.0.lock().fdata.pid = pid;
365         status_file.0.lock().fdata.ftype = ProcFileType::ProcStatus;
366 
367         //todo: 创建其他文件
368 
369         return Ok(());
370     }
371 
372     /// @brief 解除进程注册
373     ///
374     pub fn unregister_pid(&self, pid: Pid) -> Result<(), SystemError> {
375         // 获取当前inode
376         let proc: Arc<dyn IndexNode> = self.root_inode();
377         // 获取进程文件夹
378         let pid_dir: Arc<dyn IndexNode> = proc.find(&pid.to_string())?;
379         // 删除进程文件夹下文件
380         pid_dir.unlink("status")?;
381 
382         // 查看进程文件是否还存在
383         // let pf= pid_dir.find("status").expect("Cannot find status");
384 
385         // 删除进程文件夹
386         proc.unlink(&pid.to_string())?;
387 
388         return Ok(());
389     }
390 }
391 
392 impl IndexNode for LockedProcFSInode {
393     fn open(&self, data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
394         // 加锁
395         let mut inode: SpinLockGuard<ProcFSInode> = self.0.lock();
396 
397         // 如果inode类型为文件夹,则直接返回成功
398         if let FileType::Dir = inode.metadata.file_type {
399             return Ok(());
400         }
401         let mut private_data = ProcfsFilePrivateData::new();
402         // 根据文件类型获取相应数据
403         let file_size = match inode.fdata.ftype {
404             ProcFileType::ProcStatus => inode.open_status(&mut private_data)?,
405             ProcFileType::ProcMeminfo => inode.open_meminfo(&mut private_data)?,
406             _ => {
407                 todo!()
408             }
409         };
410         *data = FilePrivateData::Procfs(private_data);
411         // 更新metadata里面的文件大小数值
412         inode.metadata.size = file_size;
413 
414         return Ok(());
415     }
416 
417     fn close(&self, data: &mut FilePrivateData) -> Result<(), SystemError> {
418         let guard: SpinLockGuard<ProcFSInode> = self.0.lock();
419         // 如果inode类型为文件夹,则直接返回成功
420         if let FileType::Dir = guard.metadata.file_type {
421             return Ok(());
422         }
423         // 释放data
424         *data = FilePrivateData::Procfs(ProcfsFilePrivateData::new());
425 
426         return Ok(());
427     }
428 
429     fn read_at(
430         &self,
431         offset: usize,
432         len: usize,
433         buf: &mut [u8],
434         data: &mut FilePrivateData,
435     ) -> Result<usize, SystemError> {
436         if buf.len() < len {
437             return Err(SystemError::EINVAL);
438         }
439         // 加锁
440         let inode: SpinLockGuard<ProcFSInode> = self.0.lock();
441 
442         // 检查当前inode是否为一个文件夹,如果是的话,就返回错误
443         if inode.metadata.file_type == FileType::Dir {
444             return Err(SystemError::EISDIR);
445         }
446 
447         // 获取数据信息
448         let private_data = match data {
449             FilePrivateData::Procfs(p) => p,
450             _ => {
451                 panic!("ProcFS: FilePrivateData mismatch!");
452             }
453         };
454 
455         // 根据文件类型读取相应数据
456         match inode.fdata.ftype {
457             ProcFileType::ProcStatus => return inode.proc_read(offset, len, buf, private_data),
458             ProcFileType::ProcMeminfo => return inode.proc_read(offset, len, buf, private_data),
459             ProcFileType::Default => (),
460         };
461 
462         // 默认读取
463         let start = inode.data.len().min(offset);
464         let end = inode.data.len().min(offset + len);
465 
466         // buffer空间不足
467         if buf.len() < (end - start) {
468             return Err(SystemError::ENOBUFS);
469         }
470 
471         // 拷贝数据
472         let src = &inode.data[start..end];
473         buf[0..src.len()].copy_from_slice(src);
474         return Ok(src.len());
475     }
476 
477     fn write_at(
478         &self,
479         _offset: usize,
480         _len: usize,
481         _buf: &[u8],
482         _data: &mut FilePrivateData,
483     ) -> Result<usize, SystemError> {
484         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
485     }
486 
487     fn fs(&self) -> Arc<dyn FileSystem> {
488         return self.0.lock().fs.upgrade().unwrap();
489     }
490 
491     fn as_any_ref(&self) -> &dyn core::any::Any {
492         self
493     }
494 
495     fn metadata(&self) -> Result<Metadata, SystemError> {
496         let inode = self.0.lock();
497         let metadata = inode.metadata.clone();
498 
499         return Ok(metadata);
500     }
501 
502     fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
503         let mut inode = self.0.lock();
504         inode.metadata.atime = metadata.atime;
505         inode.metadata.mtime = metadata.mtime;
506         inode.metadata.ctime = metadata.ctime;
507         inode.metadata.mode = metadata.mode;
508         inode.metadata.uid = metadata.uid;
509         inode.metadata.gid = metadata.gid;
510 
511         return Ok(());
512     }
513 
514     fn resize(&self, len: usize) -> Result<(), SystemError> {
515         let mut inode = self.0.lock();
516         if inode.metadata.file_type == FileType::File {
517             inode.data.resize(len, 0);
518             return Ok(());
519         } else {
520             return Err(SystemError::EINVAL);
521         }
522     }
523 
524     fn create_with_data(
525         &self,
526         name: &str,
527         file_type: FileType,
528         mode: ModeType,
529         data: usize,
530     ) -> Result<Arc<dyn IndexNode>, SystemError> {
531         // 获取当前inode
532         let mut inode = self.0.lock();
533         // 如果当前inode不是文件夹,则返回
534         if inode.metadata.file_type != FileType::Dir {
535             return Err(SystemError::ENOTDIR);
536         }
537         // 如果有重名的,则返回
538         if inode.children.contains_key(name) {
539             return Err(SystemError::EEXIST);
540         }
541 
542         // 创建inode
543         let result: Arc<LockedProcFSInode> =
544             Arc::new(LockedProcFSInode(SpinLock::new(ProcFSInode {
545                 parent: inode.self_ref.clone(),
546                 self_ref: Weak::default(),
547                 children: BTreeMap::new(),
548                 data: Vec::new(),
549                 metadata: Metadata {
550                     dev_id: 0,
551                     inode_id: generate_inode_id(),
552                     size: 0,
553                     blk_size: 0,
554                     blocks: 0,
555                     atime: TimeSpec::default(),
556                     mtime: TimeSpec::default(),
557                     ctime: TimeSpec::default(),
558                     file_type: file_type,
559                     mode: mode,
560                     nlinks: 1,
561                     uid: 0,
562                     gid: 0,
563                     raw_dev: DeviceNumber::from(data as u32),
564                 },
565                 fs: inode.fs.clone(),
566                 fdata: InodeInfo {
567                     pid: Pid::new(0),
568                     ftype: ProcFileType::Default,
569                 },
570             })));
571 
572         // 初始化inode的自引用的weak指针
573         result.0.lock().self_ref = Arc::downgrade(&result);
574 
575         // 将子inode插入父inode的B树中
576         inode.children.insert(String::from(name), result.clone());
577 
578         return Ok(result);
579     }
580 
581     fn link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), SystemError> {
582         let other: &LockedProcFSInode = other
583             .downcast_ref::<LockedProcFSInode>()
584             .ok_or(SystemError::EPERM)?;
585         let mut inode: SpinLockGuard<ProcFSInode> = self.0.lock();
586         let mut other_locked: SpinLockGuard<ProcFSInode> = other.0.lock();
587 
588         // 如果当前inode不是文件夹,那么报错
589         if inode.metadata.file_type != FileType::Dir {
590             return Err(SystemError::ENOTDIR);
591         }
592 
593         // 如果另一个inode是文件夹,那么也报错
594         if other_locked.metadata.file_type == FileType::Dir {
595             return Err(SystemError::EISDIR);
596         }
597 
598         // 如果当前文件夹下已经有同名文件,也报错。
599         if inode.children.contains_key(name) {
600             return Err(SystemError::EEXIST);
601         }
602 
603         inode
604             .children
605             .insert(String::from(name), other_locked.self_ref.upgrade().unwrap());
606 
607         // 增加硬链接计数
608         other_locked.metadata.nlinks += 1;
609         return Ok(());
610     }
611 
612     fn unlink(&self, name: &str) -> Result<(), SystemError> {
613         let mut inode: SpinLockGuard<ProcFSInode> = self.0.lock();
614         // 如果当前inode不是目录,那么也没有子目录/文件的概念了,因此要求当前inode的类型是目录
615         if inode.metadata.file_type != FileType::Dir {
616             return Err(SystemError::ENOTDIR);
617         }
618         // 不允许删除当前文件夹,也不允许删除上一个目录
619         if name == "." || name == ".." {
620             return Err(SystemError::ENOTEMPTY);
621         }
622 
623         // 获得要删除的文件的inode
624         let to_delete = inode.children.get(name).ok_or(SystemError::ENOENT)?;
625         // 减少硬链接计数
626         to_delete.0.lock().metadata.nlinks -= 1;
627         // 在当前目录中删除这个子目录项
628         inode.children.remove(name);
629         return Ok(());
630     }
631 
632     fn move_(
633         &self,
634         _old_name: &str,
635         _target: &Arc<dyn IndexNode>,
636         _new_name: &str,
637     ) -> Result<(), SystemError> {
638         return Err(SystemError::EOPNOTSUPP_OR_ENOTSUP);
639     }
640 
641     fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
642         let inode = self.0.lock();
643 
644         if inode.metadata.file_type != FileType::Dir {
645             return Err(SystemError::ENOTDIR);
646         }
647 
648         match name {
649             "" | "." => {
650                 return Ok(inode.self_ref.upgrade().ok_or(SystemError::ENOENT)?);
651             }
652 
653             ".." => {
654                 return Ok(inode.parent.upgrade().ok_or(SystemError::ENOENT)?);
655             }
656             name => {
657                 // 在子目录项中查找
658                 return Ok(inode.children.get(name).ok_or(SystemError::ENOENT)?.clone());
659             }
660         }
661     }
662 
663     fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> {
664         let inode: SpinLockGuard<ProcFSInode> = self.0.lock();
665         if inode.metadata.file_type != FileType::Dir {
666             return Err(SystemError::ENOTDIR);
667         }
668 
669         match ino.into() {
670             0 => {
671                 return Ok(String::from("."));
672             }
673             1 => {
674                 return Ok(String::from(".."));
675             }
676             ino => {
677                 // 暴力遍历所有的children,判断inode id是否相同
678                 // TODO: 优化这里,这个地方性能很差!
679                 let mut key: Vec<String> = inode
680                     .children
681                     .keys()
682                     .filter(|k| {
683                         inode
684                             .children
685                             .get(*k)
686                             .unwrap()
687                             .0
688                             .lock()
689                             .metadata
690                             .inode_id
691                             .into()
692                             == ino
693                     })
694                     .cloned()
695                     .collect();
696 
697                 match key.len() {
698                         0=>{return Err(SystemError::ENOENT);}
699                         1=>{return Ok(key.remove(0));}
700                         _ => panic!("Procfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
701                     }
702             }
703         }
704     }
705 
706     fn list(&self) -> Result<Vec<String>, SystemError> {
707         let info = self.metadata()?;
708         if info.file_type != FileType::Dir {
709             return Err(SystemError::ENOTDIR);
710         }
711 
712         let mut keys: Vec<String> = Vec::new();
713         keys.push(String::from("."));
714         keys.push(String::from(".."));
715         keys.append(&mut self.0.lock().children.keys().cloned().collect());
716 
717         return Ok(keys);
718     }
719 }
720 
721 /// @brief 向procfs注册进程
722 pub fn procfs_register_pid(pid: Pid) -> Result<(), SystemError> {
723     let procfs_inode = ROOT_INODE().find("proc")?;
724 
725     let procfs_inode = procfs_inode
726         .downcast_ref::<LockedProcFSInode>()
727         .expect("Failed to find procfs' root inode");
728     let fs = procfs_inode.fs();
729     let procfs: &ProcFS = fs.as_any_ref().downcast_ref::<ProcFS>().unwrap();
730 
731     // 调用注册函数
732     procfs.register_pid(pid)?;
733 
734     return Ok(());
735 }
736 
737 /// @brief 在ProcFS中,解除进程的注册
738 pub fn procfs_unregister_pid(pid: Pid) -> Result<(), SystemError> {
739     // 获取procfs实例
740     let procfs_inode: Arc<dyn IndexNode> = ROOT_INODE().find("proc")?;
741 
742     let procfs_inode: &LockedProcFSInode = procfs_inode
743         .downcast_ref::<LockedProcFSInode>()
744         .expect("Failed to find procfs' root inode");
745     let fs: Arc<dyn FileSystem> = procfs_inode.fs();
746     let procfs: &ProcFS = fs.as_any_ref().downcast_ref::<ProcFS>().unwrap();
747 
748     // 调用解除注册函数
749     return procfs.unregister_pid(pid);
750 }
751 
752 pub fn procfs_init() -> Result<(), SystemError> {
753     static INIT: Once = Once::new();
754     let mut result = None;
755     INIT.call_once(|| {
756         kinfo!("Initializing ProcFS...");
757         // 创建 procfs 实例
758         let procfs: Arc<ProcFS> = ProcFS::new();
759 
760         // procfs 挂载
761         let _t = ROOT_INODE()
762             .find("proc")
763             .expect("Cannot find /proc")
764             .mount(procfs)
765             .expect("Failed to mount proc");
766         kinfo!("ProcFS mounted.");
767         result = Some(Ok(()));
768     });
769 
770     return result.unwrap();
771 }
772