Skip to main content

starnix_modules_pstore/
lib.rs

1// Copyright 2025 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#![recursion_limit = "512"]
6
7use bootreason::get_console_ramoops;
8use starnix_core::task::CurrentTask;
9use starnix_core::vfs::pseudo::simple_directory::SimpleDirectory;
10use starnix_core::vfs::pseudo::simple_file::BytesFile;
11use starnix_core::vfs::{
12    CacheMode, FileSystem, FileSystemHandle, FileSystemOps, FileSystemOptions, FsStr,
13};
14
15use starnix_types::vfs::default_statfs;
16use starnix_uapi::errors::Errno;
17use starnix_uapi::file_mode::mode;
18use starnix_uapi::{PSTOREFS_MAGIC, statfs};
19
20struct PstoreFsHandle {
21    fs_handle: FileSystemHandle,
22}
23
24pub fn pstore_fs(
25    current_task: &CurrentTask,
26    options: FileSystemOptions,
27) -> Result<FileSystemHandle, Errno> {
28    let handle = current_task.kernel().expando.get_or_try_init(|| {
29        Ok(PstoreFsHandle { fs_handle: PstoreFs::new_fs(current_task, options)? })
30    })?;
31    Ok(handle.fs_handle.clone())
32}
33
34pub struct PstoreFs;
35
36impl FileSystemOps for PstoreFs {
37    fn statfs(&self, _fs: &FileSystem, _current_task: &CurrentTask) -> Result<statfs, Errno> {
38        Ok(default_statfs(PSTOREFS_MAGIC))
39    }
40
41    fn name(&self) -> &'static FsStr {
42        "pstore".into()
43    }
44}
45
46impl PstoreFs {
47    pub fn new_fs(
48        current_task: &CurrentTask,
49        options: FileSystemOptions,
50    ) -> Result<FileSystemHandle, Errno> {
51        let kernel = current_task.kernel();
52        let fs = FileSystem::new(kernel, CacheMode::Permanent, PstoreFs, options)?;
53
54        let dir = SimpleDirectory::new();
55        dir.edit(&fs, |dir| {
56            if let Some(ramoops_contents) = get_console_ramoops() {
57                let ramoops_contents_0 = ramoops_contents.clone();
58                dir.entry(
59                    "console-ramoops-0",
60                    BytesFile::new_node(ramoops_contents_0),
61                    mode!(IFREG, 0o440),
62                );
63                dir.entry(
64                    "console-ramoops",
65                    BytesFile::new_node(ramoops_contents),
66                    mode!(IFREG, 0o440),
67                );
68            }
69        });
70
71        let root_ino = fs.allocate_ino();
72        fs.create_root(root_ino, dir);
73        Ok(fs)
74    }
75}