feat: Implement std_fs_call handling to initfs, ramfs, acpi and xhci

This commit is contained in:
Ibuki Omatsu
2026-02-28 15:15:16 +00:00
committed by Jeremy Soller
parent 9624cd3c2c
commit 2738f69224
27 changed files with 512 additions and 306 deletions
Generated
+63 -61
View File
@@ -14,7 +14,7 @@ dependencies = [
"pcid",
"redox-scheme",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"spin 0.9.8",
]
@@ -48,7 +48,7 @@ dependencies = [
"plain",
"redox-scheme",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"ron",
"rustc-hash",
"serde",
@@ -68,7 +68,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -190,7 +190,7 @@ dependencies = [
"libc",
"libredox",
"redox-scheme",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -221,7 +221,7 @@ dependencies = [
"fdt 0.2.0-alpha1",
"libredox",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -236,7 +236,7 @@ dependencies = [
"orbclient",
"pcid",
"redox-scheme",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -438,7 +438,7 @@ dependencies = [
"libredox",
"log",
"redox-log",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -519,7 +519,7 @@ dependencies = [
"libc",
"libredox",
"redox-scheme",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -583,7 +583,7 @@ dependencies = [
"log",
"partitionlib",
"redox-scheme",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -597,7 +597,7 @@ dependencies = [
"libredox",
"log",
"redox-scheme",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -607,7 +607,7 @@ dependencies = [
"daemon",
"libredox",
"redox-scheme",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -660,7 +660,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -740,7 +740,7 @@ dependencies = [
"ransid",
"redox-scheme",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -759,7 +759,7 @@ dependencies = [
"ransid",
"redox-scheme",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -891,7 +891,7 @@ dependencies = [
[[package]]
name = "generic-rt"
version = "0.1.0"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#27b4c3ed907f8037145616e653c36b276d8ab7d0"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#02ac27bf4bf493b9a736f66dee681a0cece1c43d"
[[package]]
name = "getrandom"
@@ -949,7 +949,7 @@ dependencies = [
"libredox",
"log",
"redox-ioctl",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -1069,7 +1069,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -1084,7 +1084,7 @@ dependencies = [
"pcid",
"redox-scheme",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"spin 0.9.8",
]
@@ -1108,7 +1108,7 @@ dependencies = [
"range-alloc",
"redox-scheme",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"void",
]
@@ -1147,7 +1147,7 @@ dependencies = [
"log",
"orbclient",
"redox-scheme",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -1172,7 +1172,7 @@ dependencies = [
"redox-rt",
"redox-scheme",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -1198,7 +1198,7 @@ dependencies = [
"libredox",
"pcid",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -1231,14 +1231,15 @@ checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
[[package]]
name = "libredox"
version = "0.1.12"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616"
checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a"
dependencies = [
"bitflags 2.11.0",
"ioslice",
"libc",
"redox_syscall 0.7.1",
"plain",
"redox_syscall 0.7.3",
]
[[package]]
@@ -1262,7 +1263,7 @@ dependencies = [
"driver-block",
"libredox",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -1287,7 +1288,7 @@ dependencies = [
"daemon",
"libredox",
"redox-scheme",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -1384,7 +1385,7 @@ dependencies = [
"partitionlib",
"pcid",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"smallvec 1.15.1",
]
@@ -1510,7 +1511,7 @@ dependencies = [
"pico-args",
"plain",
"redox-scheme",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"serde",
]
@@ -1525,7 +1526,7 @@ dependencies = [
"log",
"pcid",
"pico-args",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"serde",
"toml",
]
@@ -1611,7 +1612,7 @@ dependencies = [
"orbclient",
"redox-scheme",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -1622,7 +1623,7 @@ dependencies = [
"libredox",
"redox-scheme",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"redox_termios",
]
@@ -1655,7 +1656,7 @@ dependencies = [
"indexmap",
"libredox",
"redox-scheme",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"slab",
]
@@ -1743,7 +1744,7 @@ dependencies = [
"rand_core 0.5.1",
"raw-cpuid",
"redox-scheme",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"sha2",
]
@@ -1804,10 +1805,10 @@ dependencies = [
[[package]]
name = "redox-ioctl"
version = "0.1.0"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#27b4c3ed907f8037145616e653c36b276d8ab7d0"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#02ac27bf4bf493b9a736f66dee681a0cece1c43d"
dependencies = [
"drm-sys",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -1830,32 +1831,33 @@ checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717"
[[package]]
name = "redox-rt"
version = "0.1.0"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#27b4c3ed907f8037145616e653c36b276d8ab7d0"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#02ac27bf4bf493b9a736f66dee681a0cece1c43d"
dependencies = [
"bitflags 2.11.0",
"generic-rt",
"goblin",
"ioslice",
"libredox",
"plain",
"redox-path",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
name = "redox-scheme"
version = "0.9.1"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ef5279a1ad9567f8a87818ba80320afdf858853db93742c2bb32be31a82ccdb"
checksum = "e58cb7dee1058575f320f9bfa32c7c0eda857e285c2a163a0eb595d37add09cd"
dependencies = [
"libredox",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
name = "redox_event"
version = "0.4.5"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3514da49aa6ca4cff5088a1b382ef3a0d9149964d29bb49ebd03fd66cc575a18"
checksum = "4ea3e412d205440c7b0218af26247226f979ed1201674cda7a33cc70609084b5"
dependencies = [
"bitflags 2.11.0",
"libredox",
@@ -1873,7 +1875,7 @@ dependencies = [
"redox-rt",
"redox-scheme",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"smoltcp",
]
@@ -1888,9 +1890,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.7.1"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b"
checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16"
dependencies = [
"bitflags 2.11.0",
]
@@ -1910,7 +1912,7 @@ dependencies = [
"libredox",
"qemu-exit",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"redox_termios",
]
@@ -1986,7 +1988,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -2001,7 +2003,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -2039,7 +2041,7 @@ dependencies = [
"log",
"redox-scheme",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"spin 0.9.8",
]
@@ -2479,7 +2481,7 @@ dependencies = [
"inputd",
"log",
"orbclient",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"rehid",
"xhcid",
]
@@ -2490,7 +2492,7 @@ version = "0.1.0"
dependencies = [
"common",
"log",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"xhcid",
]
@@ -2504,7 +2506,7 @@ dependencies = [
"libredox",
"plain",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"thiserror 1.0.69",
"xhcid",
]
@@ -2542,7 +2544,7 @@ dependencies = [
"orbclient",
"pcid",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -2571,7 +2573,7 @@ dependencies = [
"orbclient",
"ransid",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
@@ -2587,7 +2589,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"spin 0.10.0",
"static_assertions",
"thiserror 1.0.69",
@@ -2606,7 +2608,7 @@ dependencies = [
"log",
"pcid",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"static_assertions",
"thiserror 1.0.69",
]
@@ -2629,7 +2631,7 @@ dependencies = [
"orbclient",
"pcid",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"spin 0.9.8",
"static_assertions",
"virtio-core",
@@ -2646,7 +2648,7 @@ dependencies = [
"libredox",
"log",
"pcid",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"static_assertions",
"virtio-core",
]
@@ -2979,7 +2981,7 @@ dependencies = [
"plain",
"redox-scheme",
"redox_event",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
"regex",
"serde",
"serde_json",
@@ -3015,7 +3017,7 @@ dependencies = [
"daemon",
"libredox",
"redox-scheme",
"redox_syscall 0.7.1",
"redox_syscall 0.7.3",
]
[[package]]
+4 -4
View File
@@ -76,14 +76,14 @@ exclude = ["bootstrap"]
anyhow = "1"
libc = "0.2.181"
log = "0.4"
libredox = "0.1.12"
libredox = "0.1.14"
orbclient = { git = "https://gitlab.redox-os.org/redox-os/orbclient" }
redox_event = "0.4.3"
redox_event = "0.4.6"
redox-ioctl = { git = "https://gitlab.redox-os.org/redox-os/relibc.git" }
redox-log = { git = "https://gitlab.redox-os.org/redox-os/redox-log.git" }
redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc.git", default-features = false }
redox-scheme = "0.9.1"
redox_syscall = "0.7.1"
redox-scheme = "0.11.0"
redox_syscall = "0.7.3"
redox_termios = "0.1.3"
serde = { version = "1", features = ["derive"] }
toml = "1"
+9 -8
View File
@@ -41,7 +41,7 @@ checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "generic-rt"
version = "0.1.0"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#d0593f54804639117ba5e8d554dd118f634917d3"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#fccd849d2230b23e5fbb2cb5b24e5237d37eb8f1"
[[package]]
name = "goblin"
@@ -77,12 +77,13 @@ checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5"
[[package]]
name = "libredox"
version = "0.1.12"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616"
checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a"
dependencies = [
"bitflags",
"libc",
"plain",
"redox_syscall",
]
@@ -150,7 +151,7 @@ checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717"
[[package]]
name = "redox-rt"
version = "0.1.0"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#d0593f54804639117ba5e8d554dd118f634917d3"
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#fccd849d2230b23e5fbb2cb5b24e5237d37eb8f1"
dependencies = [
"bitflags",
"generic-rt",
@@ -163,9 +164,9 @@ dependencies = [
[[package]]
name = "redox-scheme"
version = "0.9.1"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ef5279a1ad9567f8a87818ba80320afdf858853db93742c2bb32be31a82ccdb"
checksum = "e58cb7dee1058575f320f9bfa32c7c0eda857e285c2a163a0eb595d37add09cd"
dependencies = [
"libredox",
"redox_syscall",
@@ -173,9 +174,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.7.1"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b"
checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16"
dependencies = [
"bitflags",
]
+3 -3
View File
@@ -15,12 +15,12 @@ hashbrown = { version = "0.15", default-features = false, features = [
"default-hasher",
] }
linked_list_allocator = "0.10"
libredox = { version = "0.1.12", default-features = false }
libredox = { version = "0.1.14", default-features = false, features = ["protocol"] }
log = { version = "0.4", default-features = false }
plain = "0.2"
redox-initfs = { path = "../initfs", default-features = false }
redox_syscall = { version = "0.7.1", default-features = false }
redox-scheme = { version = "0.9.1", default-features = false }
redox_syscall = "0.7.3"
redox-scheme = { version = "0.11.0", default-features = false }
redox-path = "0.3.1"
slab = { version = "0.4.9", default-features = false }
arrayvec = { version = "0.7.6", default-features = false }
+2 -2
View File
@@ -5,10 +5,10 @@ use core::ffi::CStr;
use core::str::FromStr;
use hashbrown::HashMap;
use syscall::CallFlags;
use syscall::data::{GlobalSchemes, KernelSchemeInfo};
use syscall::flag::{O_CLOEXEC, O_RDONLY, O_STAT};
use syscall::{EINTR, Error};
use syscall::CallFlags;
use syscall::{Error, EINTR};
use redox_rt::proc::*;
+6 -2
View File
@@ -9,7 +9,10 @@ use hashbrown::HashMap;
use redox_initfs::{InitFs, Inode, InodeDir, InodeKind, InodeStruct, types::Timespec};
use redox_rt::proc::FdGuard;
use redox_scheme::{CallerCtx, OpenResult, RequestKind, scheme::SchemeSync};
use redox_scheme::{
CallerCtx, OpenResult, RequestKind,
scheme::{SchemeState, SchemeSync},
};
use redox_scheme::{SignalBehavior, Socket};
use syscall::PAGE_SIZE;
@@ -388,6 +391,7 @@ pub fn run(
scheme_creation_cap: usize,
) -> ! {
log::info!("bootstrap: starting initfs scheme");
let mut state = SchemeState::new();
let mut scheme = InitFsScheme::new(bytes);
let socket = Socket::create_inner(scheme_creation_cap, false)
@@ -421,7 +425,7 @@ pub fn run(
};
match req.kind() {
RequestKind::Call(req) => {
let resp = req.handle_sync(&mut scheme);
let resp = req.handle_sync(&mut scheme, &mut state);
if !socket
.write_response(resp, SignalBehavior::Restart)
+4 -3
View File
@@ -6,14 +6,14 @@ use core::cell::RefCell;
use core::fmt::Debug;
use core::mem;
use hashbrown::HashMap;
use libredox::protocol::{NsDup, NsPermissions};
use log::{error, warn};
use redox_path::RedoxPath;
use redox_path::RedoxScheme;
use redox_rt::proc::FdGuard;
use redox_rt::protocol::{NsDup, NsPermissions};
use redox_scheme::{
CallerCtx, OpenResult, RequestKind, Response, SendFdRequest, SignalBehavior, Socket,
scheme::SchemeSync,
scheme::{SchemeState, SchemeSync},
};
use syscall::Stat;
use syscall::dirent::{DirEntry, DirentBuf, DirentKind};
@@ -495,6 +495,7 @@ pub fn run(
let socket = Socket::create_inner(scheme_creation_cap, false)
.expect("failed to open init namespace scheme socket");
let mut state = SchemeState::new();
let mut scheme = NamespaceScheme::new(&socket, schemes, FdGuard::new(scheme_creation_cap));
// send namespace fd to bootstrap
@@ -523,7 +524,7 @@ pub fn run(
};
match req.kind() {
RequestKind::Call(req) => {
let resp = req.handle_sync(&mut scheme);
let resp = req.handle_sync(&mut scheme, &mut state);
if !socket
.write_response(resp, SignalBehavior::Restart)
+2 -2
View File
@@ -18,11 +18,11 @@ use arrayvec::ArrayString;
use hashbrown::hash_map::{Entry, OccupiedEntry, VacantEntry};
use hashbrown::{DefaultHashBuilder, HashMap, HashSet};
use redox_rt::proc::FdGuard;
use redox_rt::protocol::{
use libredox::protocol::{
ProcCall, ProcKillTarget, ProcMeta, RtSigInfo, SIGCHLD, SIGCONT, SIGHUP, SIGKILL, SIGSTOP,
SIGTSTP, SIGTTIN, SIGTTOU, ThreadCall, WaitFlags,
};
use redox_rt::proc::FdGuard;
use redox_scheme::scheme::{IntoTag, Op, OpCall};
use redox_scheme::{
CallerCtx, Id, OpenResult, Request, RequestKind, Response, SendFdRequest, SignalBehavior,
+3 -2
View File
@@ -7,7 +7,7 @@ use std::sync::Arc;
use ::acpi::aml::op_region::{RegionHandler, RegionSpace};
use event::{EventFlags, RawEventQueue};
use redox_scheme::{
scheme::{register_sync_scheme, SchemeSync},
scheme::{register_sync_scheme, SchemeState, SchemeSync},
RequestKind, Response, SignalBehavior, Socket,
};
use syscall::{EAGAIN, EWOULDBLOCK};
@@ -85,6 +85,7 @@ fn daemon(daemon: daemon::Daemon) -> ! {
let mut event_queue = RawEventQueue::new().expect("acpid: failed to create event queue");
let socket = Socket::nonblock().expect("acpid: failed to create disk scheme");
let mut state = SchemeState::new();
let mut scheme = self::scheme::AcpiScheme::new(&acpi_context, &socket);
event_queue
@@ -129,7 +130,7 @@ fn daemon(daemon: daemon::Daemon) -> ! {
};
match req.kind() {
RequestKind::Call(call) => {
let response = call.handle_sync(&mut scheme);
let response = call.handle_sync(&mut scheme, &mut state);
socket
.write_response(response, SignalBehavior::Restart)
.expect("acpid: failed to write response");
+1 -3
View File
@@ -504,10 +504,8 @@ impl SchemeSync for AcpiScheme<'_, '_> {
Ok(num_fds)
}
}
impl AcpiScheme<'_, '_> {
pub fn on_close(&mut self, id: usize) {
fn on_close(&mut self, id: usize) {
self.handles.remove(&id);
}
}
+6 -2
View File
@@ -2,7 +2,10 @@
use inputd::ProducerHandle;
use pcid_interface::PciFunctionHandle;
use redox_scheme::{scheme::register_sync_scheme, RequestKind, SignalBehavior, Socket};
use redox_scheme::{
scheme::{register_sync_scheme, SchemeState},
RequestKind, SignalBehavior, Socket,
};
use crate::bga::Bga;
use crate::scheme::BgaScheme;
@@ -39,6 +42,7 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
let mut bga = unsafe { Bga::new(bar) };
log::debug!("BGA {}x{}", bga.width(), bga.height());
let mut state = SchemeState::new();
let mut scheme = BgaScheme {
bga,
display: ProducerHandle::new().ok(),
@@ -62,7 +66,7 @@ fn daemon(daemon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> ! {
};
match request.kind() {
RequestKind::Call(call) => {
let response = call.handle_sync(&mut scheme);
let response = call.handle_sync(&mut scheme, &mut state);
socket
.write_response(response, SignalBehavior::Restart)
+85 -68
View File
@@ -19,7 +19,7 @@ use graphics_ipc::v1::CursorDamage;
use graphics_ipc::v2::Damage;
use inputd::{VtEvent, VtEventKind};
use libredox::Fd;
use redox_scheme::scheme::{register_scheme_inner, SchemeSync};
use redox_scheme::scheme::{register_scheme_inner, SchemeState, SchemeSync};
use redox_scheme::{CallerCtx, OpenResult, RequestKind, SignalBehavior, Socket};
use syscall::schemev2::NewFdFlags;
use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EBADF, EINVAL, ENOENT, EOPNOTSUPP};
@@ -90,36 +90,8 @@ pub struct CursorPlane<C: CursorFramebuffer> {
pub trait CursorFramebuffer {}
pub struct GraphicsScheme<T: GraphicsAdapter> {
adapter: T,
scheme_name: String,
disable_graphical_debug: Option<File>,
socket: Socket,
objects: DrmObjects<T>,
standard_properties: StandardProperties,
next_id: usize,
handles: BTreeMap<usize, Handle<T>>,
active_vt: usize,
vts: HashMap<usize, VtState<T>>,
}
struct VtState<T: GraphicsAdapter> {
display_fbs: Vec<Arc<T::Framebuffer>>,
cursor_plane: Option<CursorPlane<T::Cursor>>,
}
enum Handle<T: GraphicsAdapter> {
V1Screen {
vt: usize,
screen: usize,
},
V2 {
vt: usize,
next_id: u32,
fbs: HashMap<u32, Arc<T::Framebuffer>>,
},
SchemeRoot,
inner: GraphicsSchemeInner<T>,
state: SchemeState,
}
impl<T: GraphicsAdapter> GraphicsScheme<T> {
@@ -153,7 +125,7 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
adapter.probe_connector(&mut objects, &standard_properties, connector_id)
}
let mut scheme = GraphicsScheme {
let mut inner = GraphicsSchemeInner {
adapter,
scheme_name,
disable_graphical_debug,
@@ -166,41 +138,42 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
vts: HashMap::new(),
};
let cap_id = scheme
.scheme_root()
.expect("failed to get this scheme root");
register_scheme_inner(&scheme.socket, &scheme.scheme_name, cap_id)
let cap_id = inner.scheme_root().expect("failed to get this scheme root");
register_scheme_inner(&inner.socket, &inner.scheme_name, cap_id)
.expect("failed to register graphics scheme root");
scheme
Self {
inner,
state: SchemeState::new(),
}
}
pub fn event_handle(&self) -> &Fd {
self.socket.inner()
self.inner.socket.inner()
}
pub fn adapter(&self) -> &T {
&self.adapter
&self.inner.adapter
}
pub fn adapter_mut(&mut self) -> &mut T {
&mut self.adapter
&mut self.inner.adapter
}
pub fn objects(&self) -> &DrmObjects<T> {
&self.objects
&self.inner.objects
}
pub fn objects_mut(&mut self) -> &mut DrmObjects<T> {
&mut self.objects
&mut self.inner.objects
}
pub fn adapter_and_objects_mut(&mut self) -> (&mut T, &mut DrmObjects<T>) {
(&mut self.adapter, &mut self.objects)
(&mut self.inner.adapter, &mut self.inner.objects)
}
pub fn standard_properties(&self) -> StandardProperties {
self.standard_properties
self.inner.standard_properties
}
pub fn handle_vt_event(&mut self, vt_event: VtEvent) {
@@ -212,21 +185,29 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
// first time. This way the kernel graphical debug remains enabled if the
// userspace logging infrastructure doesn't start up because for example a
// kernel panic happened prior to it starting up or logd crashed.
if let Some(mut disable_graphical_debug) = self.disable_graphical_debug.take() {
if let Some(mut disable_graphical_debug) = self.inner.disable_graphical_debug.take()
{
let _ = disable_graphical_debug.write(&[1]);
}
self.active_vt = vt_event.vt;
self.inner.active_vt = vt_event.vt;
let vt_state =
Self::get_or_create_vt(&mut self.adapter, &mut self.vts, vt_event.vt);
let vt_state = GraphicsSchemeInner::get_or_create_vt(
&mut self.inner.adapter,
&mut self.inner.vts,
vt_event.vt,
);
for (display_id, fb) in vt_state.display_fbs.iter().enumerate() {
Self::update_whole_screen(&mut self.adapter, display_id, fb);
GraphicsSchemeInner::update_whole_screen(
&mut self.inner.adapter,
display_id,
fb,
);
}
if let Some(cursor_plane) = &vt_state.cursor_plane {
self.adapter.handle_cursor(cursor_plane, true);
self.inner.adapter.handle_cursor(cursor_plane, true);
}
}
@@ -246,7 +227,7 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
/// file.
pub fn tick(&mut self) -> io::Result<()> {
loop {
let request = match self.socket.next_request(SignalBehavior::Restart) {
let request = match self.inner.socket.next_request(SignalBehavior::Restart) {
Ok(Some(request)) => request,
Ok(None) => {
// Scheme likely got unmounted
@@ -258,13 +239,14 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
match request.kind() {
RequestKind::Call(call) => {
let response = call.handle_sync(self);
self.socket
let response = call.handle_sync(&mut self.inner, &mut self.state);
self.inner
.socket
.write_response(response, SignalBehavior::Restart)
.expect("driver-graphics: failed to write response");
}
RequestKind::OnClose { id } => {
self.on_close(id);
self.inner.on_close(id);
}
_ => (),
}
@@ -272,20 +254,42 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
Ok(())
}
}
fn update_whole_screen(adapter: &mut T, screen: usize, framebuffer: &T::Framebuffer) {
adapter.update_plane(
screen,
framebuffer,
Damage {
x: 0,
y: 0,
width: framebuffer.width(),
height: framebuffer.height(),
},
);
}
struct GraphicsSchemeInner<T: GraphicsAdapter> {
adapter: T,
scheme_name: String,
disable_graphical_debug: Option<File>,
socket: Socket,
objects: DrmObjects<T>,
standard_properties: StandardProperties,
next_id: usize,
handles: BTreeMap<usize, Handle<T>>,
active_vt: usize,
vts: HashMap<usize, VtState<T>>,
}
struct VtState<T: GraphicsAdapter> {
display_fbs: Vec<Arc<T::Framebuffer>>,
cursor_plane: Option<CursorPlane<T::Cursor>>,
}
enum Handle<T: GraphicsAdapter> {
V1Screen {
vt: usize,
screen: usize,
},
V2 {
vt: usize,
next_id: u32,
fbs: HashMap<u32, Arc<T::Framebuffer>>,
},
SchemeRoot,
}
impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
fn get_or_create_vt<'a>(
adapter: &mut T,
vts: &'a mut HashMap<usize, VtState<T>>,
@@ -312,11 +316,24 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
}
})
}
fn update_whole_screen(adapter: &mut T, screen: usize, framebuffer: &T::Framebuffer) {
adapter.update_plane(
screen,
framebuffer,
Damage {
x: 0,
y: 0,
width: framebuffer.width(),
height: framebuffer.height(),
},
);
}
}
const MAP_FAKE_OFFSET_MULTIPLIER: usize = 0x10_000_000;
impl<T: GraphicsAdapter> SchemeSync for GraphicsScheme<T> {
impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id;
self.next_id += 1;
@@ -927,7 +944,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsScheme<T> {
}
}
impl<T: GraphicsAdapter> GraphicsScheme<T> {
impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
fn on_close(&mut self, id: usize) {
self.handles.remove(&id);
}
+3 -2
View File
@@ -13,7 +13,7 @@ use event::EventQueue;
use inputd::ConsumerHandleEvent;
use libredox::errno::EAGAIN;
use orbclient::Event;
use redox_scheme::{RequestKind, SignalBehavior, Socket};
use redox_scheme::{scheme::SchemeState, RequestKind, SignalBehavior, Socket};
use crate::scheme::FbbootlogScheme;
@@ -34,6 +34,7 @@ fn daemon(daemon: daemon::SchemeDaemon) -> ! {
let socket = Socket::nonblock().expect("fbbootlogd: failed to create fbbootlog scheme");
let mut state = SchemeState::new();
let mut scheme = FbbootlogScheme::new();
event_queue
@@ -90,7 +91,7 @@ fn daemon(daemon: daemon::SchemeDaemon) -> ! {
match request.kind() {
RequestKind::Call(call) => {
let response = call.handle_sync(&mut scheme);
let response = call.handle_sync(&mut scheme, &mut state);
socket
.write_response(response, SignalBehavior::Restart)
+27 -6
View File
@@ -3,7 +3,7 @@ use inputd::ConsumerHandleEvent;
use libredox::errno::{EAGAIN, EINTR};
use orbclient::Event;
use redox_scheme::{
scheme::{Op, SchemeResponse, SchemeSync},
scheme::{Op, SchemeResponse, SchemeState, SchemeSync},
CallerCtx, RequestKind, Response, SignalBehavior, Socket,
};
use std::env;
@@ -44,6 +44,7 @@ fn daemon(daemon: daemon::SchemeDaemon) -> ! {
)
.expect("fbcond: failed to subscribe to scheme events");
let mut state = SchemeState::new();
let mut scheme = FbconScheme::new(&vt_ids, &mut event_queue);
let _ = daemon.ready_sync_scheme(&socket, &mut scheme);
@@ -58,16 +59,23 @@ fn daemon(daemon: daemon::SchemeDaemon) -> ! {
handle_event(
&mut socket,
&mut scheme,
&mut state,
&mut blocked,
VtIndex::SCHEMA_SENTINEL,
);
for vt_i in scheme.vts.keys().copied().collect::<Vec<_>>() {
handle_event(&mut socket, &mut scheme, &mut blocked, vt_i);
handle_event(&mut socket, &mut scheme, &mut state, &mut blocked, vt_i);
}
for event in event_queue {
let event = event.expect("fbcond: failed to read event from event queue");
handle_event(&mut socket, &mut scheme, &mut blocked, event.user_data);
handle_event(
&mut socket,
&mut scheme,
&mut state,
&mut blocked,
event.user_data,
);
}
std::process::exit(0);
@@ -76,6 +84,7 @@ fn daemon(daemon: daemon::SchemeDaemon) -> ! {
fn handle_event(
socket: &mut Socket,
scheme: &mut FbconScheme,
state: &mut SchemeState,
blocked: &mut Vec<(Op, CallerCtx)>,
event: VtIndex,
) {
@@ -108,7 +117,7 @@ fn handle_event(
continue;
}
};
match op.handle_sync_dont_consume(&caller, scheme) {
match op.handle_sync_dont_consume(&caller, scheme, state) {
SchemeResponse::Opened(Err(e)) | SchemeResponse::Regular(Err(e))
if libredox::error::Error::from(e).is_wouldblock()
&& !op.is_explicitly_nonblock() =>
@@ -128,7 +137,15 @@ fn handle_event(
)
.expect("fbcond: failed to write responses to fbcon scheme");
}
};
SchemeResponse::RegularAndNotifyOnDetach(status) => {
let _ = socket
.write_response(
Response::new_notify_on_detach(status, op),
SignalBehavior::Restart,
)
.expect("fbcond: failed to write scheme");
}
}
}
RequestKind::OnClose { id } => {
scheme.on_close(id);
@@ -179,7 +196,7 @@ fn handle_event(
let (op, caller) = blocked
.get_mut(i)
.expect("vesad: Failed to get blocked request");
let resp = match op.handle_sync_dont_consume(&caller, scheme) {
let resp = match op.handle_sync_dont_consume(&caller, scheme, state) {
SchemeResponse::Opened(Err(e)) | SchemeResponse::Regular(Err(e))
if libredox::error::Error::from(e).is_wouldblock()
&& !op.is_explicitly_nonblock() =>
@@ -195,6 +212,10 @@ fn handle_event(
let (op, _) = blocked.remove(i);
Response::open_dup_like(o, op)
}
SchemeResponse::RegularAndNotifyOnDetach(status) => {
let (op, _) = blocked.remove(i);
Response::new_notify_on_detach(status, op)
}
};
let _ = socket
.write_response(resp, SignalBehavior::Restart)
+3 -2
View File
@@ -20,7 +20,7 @@ use std::sync::atomic::{AtomicUsize, Ordering};
use inputd::{ControlEvent, VtEvent, VtEventKind};
use libredox::errno::ESTALE;
use redox_scheme::scheme::SchemeSync;
use redox_scheme::scheme::{SchemeState, SchemeSync};
use redox_scheme::{CallerCtx, OpenResult, RequestKind, Response, SignalBehavior, Socket};
use orbclient::{Event, EventOption};
@@ -569,6 +569,7 @@ impl SchemeSync for InputScheme {
fn deamon(daemon: daemon::SchemeDaemon) -> anyhow::Result<()> {
// Create the ":input" scheme.
let socket_file = Socket::create()?;
let mut state = SchemeState::new();
let mut scheme = InputScheme::new();
let _ = daemon.ready_sync_scheme(&socket_file, &mut scheme);
@@ -583,7 +584,7 @@ fn deamon(daemon: daemon::SchemeDaemon) -> anyhow::Result<()> {
match request.kind() {
RequestKind::Call(call_request) => {
socket_file.write_response(
call_request.handle_sync(&mut scheme),
call_request.handle_sync(&mut scheme, &mut state),
SignalBehavior::Restart,
)?;
}
+19 -3
View File
@@ -4,7 +4,7 @@ use std::{cmp, io};
use libredox::flag::O_NONBLOCK;
use libredox::Fd;
use redox_scheme::{
scheme::{IntoTag, Op, SchemeResponse, SchemeSync},
scheme::{IntoTag, Op, SchemeResponse, SchemeState, SchemeSync},
CallerCtx, OpenResult, RequestKind, Response, SignalBehavior, Socket,
};
use syscall::schemev2::NewFdFlags;
@@ -33,6 +33,7 @@ pub trait NetworkAdapter {
pub struct NetworkScheme<T: NetworkAdapter> {
scheme: NetworkSchemeInner<T>,
state: SchemeState,
blocked: Vec<(Op, CallerCtx)>,
socket: Socket,
}
@@ -61,6 +62,7 @@ impl<T: NetworkAdapter> NetworkScheme<T> {
daemon.ready();
Self {
scheme,
state: SchemeState::new(),
blocked: Vec::new(),
socket,
}
@@ -91,7 +93,7 @@ impl<T: NetworkAdapter> NetworkScheme<T> {
let mut i = 0;
while i < self.blocked.len() {
let (op, caller) = &mut self.blocked[i];
let res = op.handle_sync_dont_consume(caller, &mut self.scheme);
let res = op.handle_sync_dont_consume(caller, &mut self.scheme, &mut self.state);
match res {
SchemeResponse::Opened(Err(Error {
errno: syscall::EWOULDBLOCK,
@@ -115,6 +117,16 @@ impl<T: NetworkAdapter> NetworkScheme<T> {
.write_response(Response::open_dup_like(o, op), SignalBehavior::Restart)
.expect("driver-network: failed to write scheme");
}
SchemeResponse::RegularAndNotifyOnDetach(status) => {
let (op, _) = self.blocked.remove(i);
let _ = self
.socket
.write_response(
Response::new_notify_on_detach(status, op),
SignalBehavior::Restart,
)
.expect("driver-network: failed to write scheme");
}
}
}
@@ -160,7 +172,8 @@ impl<T: NetworkAdapter> NetworkScheme<T> {
}
};
let resp = match op.handle_sync_dont_consume(&caller, &mut self.scheme) {
let resp = match op.handle_sync_dont_consume(&caller, &mut self.scheme, &mut self.state)
{
SchemeResponse::Opened(Err(Error {
errno: syscall::EWOULDBLOCK,
}))
@@ -172,6 +185,9 @@ impl<T: NetworkAdapter> NetworkScheme<T> {
}
SchemeResponse::Regular(r) => Response::new(r, op),
SchemeResponse::Opened(o) => Response::open_dup_like(o, op),
SchemeResponse::RegularAndNotifyOnDetach(status) => {
Response::new_notify_on_detach(status, op)
}
};
let _ = self.socket.write_response(resp, SignalBehavior::Restart)?;
}
+6 -2
View File
@@ -10,7 +10,10 @@ use pci_types::{
Bar as TyBar, CommandRegister, EndpointHeader, HeaderType, PciAddress,
PciHeader as TyPciHeader, PciPciBridgeHeader,
};
use redox_scheme::{scheme::register_sync_scheme, RequestKind, SignalBehavior};
use redox_scheme::{
scheme::{register_sync_scheme, SchemeState},
RequestKind, SignalBehavior,
};
use crate::cfg_access::Pcie;
use pcid_interface::{FullDeviceId, LegacyInterruptLine, PciBar, PciFunction, PciRom};
@@ -249,6 +252,7 @@ fn daemon(daemon: daemon::Daemon) -> ! {
info!("PCI SG-BS:DV.F VEND:DEVI CL.SC.IN.RV");
let mut state = SchemeState::new();
let mut scheme = scheme::PciScheme::new(pcie);
let socket = redox_scheme::Socket::create().expect("failed to open pci scheme socket");
@@ -316,7 +320,7 @@ fn daemon(daemon: daemon::Daemon) -> ! {
};
match request.kind() {
RequestKind::Call(call) => {
let response = call.handle_sync(&mut scheme);
let response = call.handle_sync(&mut scheme, &mut state);
socket
.write_response(response, SignalBehavior::Restart)
+102 -90
View File
@@ -11,7 +11,7 @@ use std::task::Poll;
use executor::LocalExecutor;
use libredox::Fd;
use partitionlib::{LogicalBlockSize, PartitionTable};
use redox_scheme::scheme::{register_scheme_inner, SchemeAsync};
use redox_scheme::scheme::{register_scheme_inner, SchemeAsync, SchemeState};
use redox_scheme::{CallerCtx, OpenResult, RequestKind, Response, SignalBehavior, Socket};
use syscall::dirent::DirentBuf;
use syscall::schemev2::NewFdFlags;
@@ -254,6 +254,103 @@ impl<T: Disk> DiskWrapper<T> {
}
}
pub struct DiskScheme<T> {
inner: DiskSchemeInner<T>,
state: SchemeState,
}
impl<T: Disk> DiskScheme<T> {
pub fn new(
daemon: Option<daemon::Daemon>,
scheme_name: String,
disks: BTreeMap<u32, T>,
executor: &impl ExecutorTrait,
) -> Self {
assert!(scheme_name.starts_with("disk"));
let socket = Socket::nonblock().expect("failed to create disk scheme");
let mut inner = DiskSchemeInner {
scheme_name: scheme_name,
socket,
disks: disks
.into_iter()
.map(|(k, disk)| (k, DiskWrapper::new(disk, executor)))
.collect(),
next_id: 0,
handles: BTreeMap::new(),
};
let cap_id = inner.scheme_root().expect("failed to get this scheme root");
register_scheme_inner(&inner.socket, &inner.scheme_name, cap_id)
.expect("failed to register disk scheme root");
if let Some(daemon) = daemon {
daemon.ready();
}
Self {
inner,
state: SchemeState::new(),
}
}
pub fn event_handle(&self) -> &Fd {
self.inner.socket.inner()
}
/// Process pending and new requests.
///
/// This needs to be called each time there is a new event on the scheme.
pub async fn tick(&mut self) -> io::Result<()> {
// Handle new scheme requests
loop {
let request = match self.inner.socket.next_request(SignalBehavior::Interrupt) {
Ok(Some(request)) => request,
Ok(None) => {
// Scheme likely got unmounted
// TODO: return this to caller instead
std::process::exit(0);
}
Err(error) if error.errno == EWOULDBLOCK || error.errno == EAGAIN => break,
Err(err) if err.errno == EINTR => continue,
Err(err) => return Err(err.into()),
};
let response = match request.kind() {
RequestKind::Call(call_request) => {
// TODO: Spawn a separate task for each scheme call. This would however require the
// use of a smarter buffer pool (or direct IO, or a buffer per fd) in order to do
// parallel IO. It might also require async-aware locks so that a close() is
// correctly ordered wrt IO on the same fd.
call_request
.handle_async(&mut self.inner, &mut self.state)
.await
}
RequestKind::SendFd(request) => Response::err(EOPNOTSUPP, request),
RequestKind::RecvFd(request) => Response::err(EOPNOTSUPP, request),
RequestKind::Cancellation(_cancellation_request) => {
// FIXME implement cancellation
continue;
}
RequestKind::MsyncMsg | RequestKind::MunmapMsg | RequestKind::MmapMsg => {
unreachable!()
}
RequestKind::OnClose { id } => {
self.inner.on_close(id);
continue;
}
RequestKind::RecvFd(_) => continue,
RequestKind::OnDetach { .. } => continue,
};
self.inner
.socket
.write_response(response, SignalBehavior::Restart)?;
}
Ok(())
}
}
enum Handle {
List(Vec<u8>), // entries
Disk(u32), // disk num
@@ -261,7 +358,7 @@ enum Handle {
SchemeRoot,
}
pub struct DiskScheme<T> {
struct DiskSchemeInner<T> {
scheme_name: String,
socket: Socket,
disks: BTreeMap<u32, DiskWrapper<T>>,
@@ -303,92 +400,7 @@ impl ExecutorTrait for TrivialExecutor {
}
}
impl<T: Disk> DiskScheme<T> {
pub fn new(
daemon: Option<daemon::Daemon>,
scheme_name: String,
disks: BTreeMap<u32, T>,
executor: &impl ExecutorTrait,
) -> Self {
assert!(scheme_name.starts_with("disk"));
let socket = Socket::nonblock().expect("failed to create disk scheme");
let mut scheme = Self {
scheme_name: scheme_name,
socket,
disks: disks
.into_iter()
.map(|(k, disk)| (k, DiskWrapper::new(disk, executor)))
.collect(),
next_id: 0,
handles: BTreeMap::new(),
};
let cap_id = scheme
.scheme_root()
.expect("failed to get this scheme root");
register_scheme_inner(&scheme.socket, &scheme.scheme_name, cap_id)
.expect("failed to register disk scheme root");
if let Some(daemon) = daemon {
daemon.ready();
}
scheme
}
pub fn event_handle(&self) -> &Fd {
self.socket.inner()
}
/// Process pending and new requests.
///
/// This needs to be called each time there is a new event on the scheme.
pub async fn tick(&mut self) -> io::Result<()> {
// Handle new scheme requests
loop {
let request = match self.socket.next_request(SignalBehavior::Interrupt) {
Ok(Some(request)) => request,
Ok(None) => {
// Scheme likely got unmounted
// TODO: return this to caller instead
std::process::exit(0);
}
Err(error) if error.errno == EWOULDBLOCK || error.errno == EAGAIN => break,
Err(err) if err.errno == EINTR => continue,
Err(err) => return Err(err.into()),
};
let response = match request.kind() {
RequestKind::Call(call_request) => {
// TODO: Spawn a separate task for each scheme call. This would however require the
// use of a smarter buffer pool (or direct IO, or a buffer per fd) in order to do
// parallel IO. It might also require async-aware locks so that a close() is
// correctly ordered wrt IO on the same fd.
call_request.handle_async(self).await
}
RequestKind::SendFd(request) => Response::err(EOPNOTSUPP, request),
RequestKind::RecvFd(request) => Response::err(EOPNOTSUPP, request),
RequestKind::Cancellation(_cancellation_request) => {
// FIXME implement cancellation
continue;
}
RequestKind::MsyncMsg | RequestKind::MunmapMsg | RequestKind::MmapMsg => {
unreachable!()
}
RequestKind::OnClose { id } => {
self.on_close(id);
continue;
}
RequestKind::RecvFd(_) => continue,
};
self.socket
.write_response(response, SignalBehavior::Restart)?;
}
Ok(())
}
impl<T: Disk> DiskSchemeInner<T> {
// Checks if any conflicting handles already exist
fn check_locks(&self, disk_i: u32, part_i_opt: Option<u32>) -> Result<()> {
for (_, handle) in self.handles.iter() {
@@ -419,7 +431,7 @@ impl<T: Disk> DiskScheme<T> {
}
}
impl<T: Disk> SchemeAsync for DiskScheme<T> {
impl<T: Disk> SchemeAsync for DiskSchemeInner<T> {
fn scheme_root(&mut self) -> Result<usize> {
let id = self.next_id;
self.next_id += 1;
@@ -683,7 +695,7 @@ impl<T: Disk> SchemeAsync for DiskScheme<T> {
}
}
impl<D: Disk> DiskScheme<D> {
impl<D: Disk> DiskSchemeInner<D> {
pub fn on_close(&mut self, id: usize) {
let _ = self.handles.remove(&id);
}
+6 -2
View File
@@ -37,7 +37,10 @@ use pcid_interface::irq_helpers::{
};
use pcid_interface::{PciFeature, PciFeatureInfo, PciFunctionHandle};
use redox_scheme::{scheme::register_sync_scheme, RequestKind, SignalBehavior, Socket};
use redox_scheme::{
scheme::{register_sync_scheme, SchemeState},
RequestKind, SignalBehavior, Socket,
};
use crate::xhci::{InterruptMethod, Xhci};
@@ -145,6 +148,7 @@ fn daemon_with_context_size<const N: usize>(
let scheme_name = format!("usb.{}", name);
let socket = Socket::create().expect("xhcid: failed to create usb scheme");
let mut state = SchemeState::new();
let hci = Arc::new(
Xhci::<N>::new(scheme_name.clone(), address, interrupt_method, pcid_handle)
.expect("xhcid: failed to allocate device"),
@@ -170,7 +174,7 @@ fn daemon_with_context_size<const N: usize>(
match request.kind() {
RequestKind::Call(call_request) => {
let resp = call_request.handle_sync(&mut &*hci);
let resp = call_request.handle_sync(&mut &*hci, &mut state);
socket
.write_response(resp, SignalBehavior::Restart)
.expect("xhcid: failed to write scheme");
+2 -2
View File
@@ -33,8 +33,8 @@ use redox_scheme::{CallerCtx, OpenResult};
use syscall::schemev2::NewFdFlags;
use syscall::{
Error, Result, Stat, EACCES, EBADF, EBADFD, EBADMSG, EINVAL, EIO, EISDIR, ENOENT, ENOSYS,
ENOTDIR, EPROTO, ESPIPE, MODE_CHR, MODE_DIR, MODE_FILE, O_DIRECTORY, O_RDWR, O_STAT, O_WRONLY,
SEEK_CUR, SEEK_END, SEEK_SET,
ENOTDIR, EOPNOTSUPP, EPROTO, ESPIPE, MODE_CHR, MODE_DIR, MODE_FILE, O_DIRECTORY, O_RDWR,
O_STAT, O_WRONLY, SEEK_CUR, SEEK_END, SEEK_SET,
};
use super::{port, usb};
+6 -2
View File
@@ -1,4 +1,7 @@
use redox_scheme::{scheme::SchemeSync, RequestKind, Response, SignalBehavior, Socket};
use redox_scheme::{
scheme::{SchemeState, SchemeSync},
RequestKind, Response, SignalBehavior, Socket,
};
use std::process;
use crate::scheme::LogScheme;
@@ -8,6 +11,7 @@ mod scheme;
fn daemon(daemon: daemon::SchemeDaemon) -> ! {
let socket = Socket::create().expect("logd: failed to create log scheme");
let mut state = SchemeState::new();
let mut scheme = LogScheme::new(&socket);
let _ = daemon.ready_sync_scheme(&socket, &mut scheme);
@@ -35,7 +39,7 @@ fn daemon(daemon: daemon::SchemeDaemon) -> ! {
_ => continue,
};
let response = request.handle_sync(&mut scheme);
let response = request.handle_sync(&mut scheme, &mut state);
socket
.write_response(response, SignalBehavior::Restart)
.expect("logd: failed to write responses to log scheme");
+23 -4
View File
@@ -8,7 +8,7 @@ use crate::scheme::socket::{Handle, SchemeSocket, SocketScheme};
use libredox::flag;
use libredox::Fd;
use redox_scheme::{
scheme::{IntoTag, Op, SchemeResponse, SchemeSync},
scheme::{IntoTag, Op, SchemeResponse, SchemeState, SchemeSync},
CallerCtx, RequestKind, Response, SignalBehavior, Socket,
};
use smoltcp;
@@ -316,6 +316,7 @@ where
SocketT: SchemeSocket + AnySocket<'static>,
{
scheme: socket::SocketScheme<SocketT>,
state: SchemeState,
wait_queue: WaitQueue,
}
impl<SocketT> SchemeWrapper<SocketT>
@@ -334,6 +335,7 @@ where
.map_err(|e| {
Error::from_syscall_error(e, &format!("failed to initialize {} scheme", name))
})?,
state: SchemeState::new(),
wait_queue: Vec::new(),
})
}
@@ -397,7 +399,8 @@ where
continue;
}
};
let resp = match op.handle_sync_dont_consume(&caller, &mut self.scheme) {
let resp = match op.handle_sync_dont_consume(&caller, &mut self.scheme, &mut self.state)
{
SchemeResponse::Opened(Err(SyscallError {
errno: syscall::EWOULDBLOCK,
}))
@@ -433,6 +436,9 @@ where
}
SchemeResponse::Regular(r) => Response::new(r, op),
SchemeResponse::Opened(o) => Response::open_dup_like(o, op),
SchemeResponse::RegularAndNotifyOnDetach(status) => {
Response::new_notify_on_detach(status, op)
}
};
let _ = self
.scheme
@@ -449,6 +455,7 @@ where
// Notify non-blocking sockets
let scheme = &mut self.scheme;
let state = &mut self.state;
for (&fd, handle) in &mut scheme.handles {
let Handle::File(file) = handle else {
@@ -469,7 +476,7 @@ where
while i < queue.len() {
let handle = &mut queue[i];
let (op, caller) = &mut handle.packet;
let res = op.handle_sync_dont_consume(caller, scheme);
let res = op.handle_sync_dont_consume(caller, scheme, state);
match res {
SchemeResponse::Opened(Err(SyscallError {
@@ -531,7 +538,19 @@ where
Error::from_syscall_error(e.into(), "failed to write response")
})?;
}
};
SchemeResponse::RegularAndNotifyOnDetach(status) => {
let (op, _) = queue.swap_remove(i).packet;
let _ = scheme
.scheme_file
.write_response(
Response::new_notify_on_detach(status, op),
SignalBehavior::Restart,
)
.map_err(|e| {
Error::from_syscall_error(e.into(), "failed to write response")
})?;
}
}
}
Ok(())
+33 -22
View File
@@ -3,8 +3,8 @@ mod nodes;
mod notifier;
use redox_scheme::{
scheme::register_scheme_inner, scheme::SchemeSync, CallerCtx, OpenResult, RequestKind,
Response, SignalBehavior, Socket,
scheme::{register_scheme_inner, SchemeState, SchemeSync},
CallerCtx, OpenResult, RequestKind, Response, SignalBehavior, Socket,
};
use smoltcp::wire::{EthernetAddress, IpAddress, IpCidr, Ipv4Address};
use std::cell::RefCell;
@@ -325,17 +325,9 @@ impl NetCfgFile {
}
}
enum Handle {
SchemeRoot,
File(NetCfgFile),
}
pub struct NetCfgScheme {
scheme_file: Socket,
next_fd: usize,
handles: BTreeMap<usize, Handle>,
root_node: CfgNodeRef,
notifier: NotifierRef,
inner: NetCfgSchemeInner,
state: SchemeState,
}
impl NetCfgScheme {
@@ -349,7 +341,7 @@ impl NetCfgScheme {
let dns_config = Rc::new(RefCell::new(DNSConfig {
name_server: Ipv4Address::new(8, 8, 8, 8),
}));
let mut scheme = NetCfgScheme {
let mut inner = NetCfgSchemeInner {
scheme_file,
next_fd: 1,
handles: BTreeMap::new(),
@@ -362,18 +354,21 @@ impl NetCfgScheme {
),
notifier,
};
let cap_id = scheme
let cap_id = inner
.scheme_root()
.map_err(|e| Error::from_syscall_error(e, "failed to get scheme root id"))?;
register_scheme_inner(&scheme.scheme_file, "netcfg", cap_id).map_err(|e| {
register_scheme_inner(&inner.scheme_file, "netcfg", cap_id).map_err(|e| {
Error::from_syscall_error(e, "failed to register netcfg scheme to namespace")
})?;
Ok(scheme)
Ok(Self {
inner,
state: SchemeState::new(),
})
}
pub fn on_scheme_event(&mut self) -> Result<Option<()>> {
let result = loop {
let request = match self.scheme_file.next_request(SignalBehavior::Restart) {
let request = match self.inner.scheme_file.next_request(SignalBehavior::Restart) {
Ok(Some(req)) => req,
Ok(None) => {
break Some(());
@@ -394,7 +389,7 @@ impl NetCfgScheme {
let req = match request.kind() {
RequestKind::Call(c) => c,
RequestKind::OnClose { id } => {
self.on_close(id);
self.inner.on_close(id);
continue;
}
_ => {
@@ -405,23 +400,39 @@ impl NetCfgScheme {
let op = match req.op() {
Ok(op) => op,
Err(req) => {
self.scheme_file.write_response(
self.inner.scheme_file.write_response(
Response::err(syscall::EOPNOTSUPP, req),
SignalBehavior::Restart,
);
continue;
}
};
let resp = op.handle_sync(caller, self);
let resp = op.handle_sync(caller, &mut self.inner, &mut self.state);
let _ = self
.inner
.scheme_file
.write_response(resp, SignalBehavior::Restart)
.map_err(|e| Error::from_syscall_error(e.into(), "failed to write response"))?;
};
self.notify_scheduled_fds();
self.inner.notify_scheduled_fds();
Ok(result)
}
}
enum Handle {
SchemeRoot,
File(NetCfgFile),
}
struct NetCfgSchemeInner {
scheme_file: Socket,
next_fd: usize,
handles: BTreeMap<usize, Handle>,
root_node: CfgNodeRef,
notifier: NotifierRef,
}
impl NetCfgSchemeInner {
fn notify_scheduled_fds(&mut self) {
let fds_to_notify = self.notifier.borrow_mut().get_notified_fds();
for fd in fds_to_notify {
@@ -430,7 +441,7 @@ impl NetCfgScheme {
}
}
impl SchemeSync for NetCfgScheme {
impl SchemeSync for NetCfgSchemeInner {
fn scheme_root(&mut self) -> SyscallResult<usize> {
let id = self.next_fd;
self.next_fd += 1;
+3 -2
View File
@@ -3,7 +3,7 @@ use std::{env, process};
mod filesystem;
mod scheme;
use redox_scheme::{RequestKind, SignalBehavior};
use redox_scheme::{scheme::SchemeState, RequestKind, SignalBehavior};
use self::scheme::Scheme;
@@ -16,6 +16,7 @@ fn daemon(daemon: daemon::SchemeDaemon) -> ! {
let socket = redox_scheme::Socket::create().expect("ramfs: failed to create socket");
let mut state = SchemeState::new();
let mut scheme = Scheme::new(scheme_name.clone()).expect("ramfs: failed to initialize scheme");
let _ = daemon.ready_sync_scheme(&socket, &mut scheme);
@@ -31,7 +32,7 @@ fn daemon(daemon: daemon::SchemeDaemon) -> ! {
};
match request.kind() {
RequestKind::Call(call) => {
let response = call.handle_sync(&mut scheme);
let response = call.handle_sync(&mut scheme, &mut state);
socket
.write_response(response, SignalBehavior::Restart)
+84 -3
View File
@@ -3,17 +3,19 @@ use std::convert::{TryFrom, TryInto};
use std::io::{Cursor, Seek};
use std::iter;
use std::os::unix::io::AsRawFd;
use std::{mem, str};
use syscall::dirent::{DirEntry, DirentBuf, DirentKind};
use syscall::error::{
EACCES, EBADF, EBADFD, EEXIST, EINVAL, EIO, EISDIR, ENOMEM, ENOSYS, ENOTDIR, ENOTEMPTY,
EOVERFLOW,
EOPNOTSUPP, EOVERFLOW, EPERM,
};
use syscall::flag::{
O_ACCMODE, O_CREAT, O_DIRECTORY, O_EXCL, O_RDONLY, O_RDWR, O_STAT, O_TRUNC, O_WRONLY,
StdFsCallKind, O_ACCMODE, O_CREAT, O_DIRECTORY, O_EXCL, O_RDONLY, O_RDWR, O_STAT, O_TRUNC,
O_WRONLY,
};
use syscall::schemev2::NewFdFlags;
use syscall::{Error, EventFlags, Result, Stat, StatVfs, TimeSpec, ENOENT};
use syscall::{Error, EventFlags, Result, Stat, StatVfs, StdFsCallMeta, TimeSpec, ENOENT};
use syscall::{MODE_DIR, MODE_FILE, MODE_PERM, MODE_TYPE};
use indexmap::IndexMap;
@@ -36,6 +38,7 @@ pub struct Scheme {
filesystem: Filesystem,
handles: HashMap<usize, Handle>,
next_id: usize,
proc_creds_capability: libredox::Fd,
}
impl Scheme {
/// Create the scheme, with the name being used for `fpath`.
@@ -45,6 +48,13 @@ impl Scheme {
filesystem: Filesystem::new()?,
handles: HashMap::new(),
next_id: 0,
proc_creds_capability: {
libredox::Fd::open(
"/scheme/proc/proc-creds-capability",
libredox::flag::O_RDONLY,
0,
)?
},
})
}
/// Remove a directory entry, where the entry can be both a file or a directory. Used by `unlinkat`.
@@ -641,6 +651,48 @@ impl SchemeSync for Scheme {
Ok(())
}
fn std_fs_call(
&mut self,
id: usize,
kind: StdFsCallKind,
payload: &mut [u8],
metadata: StdFsCallMeta,
ctx: &CallerCtx,
) -> Result<usize> {
match kind {
StdFsCallKind::Fchown => {
let (new_uid, new_gid) = (metadata.arg1 as u32, metadata.arg1 >> 32 as u32);
let (_pid, uid, gid) = get_uid_gid_from_pid(&self.proc_creds_capability, ctx.pid)?;
if uid != 0 && (uid != ctx.uid || gid != ctx.gid) {
return Err(Error::new(EPERM));
}
self.fchown(id, new_uid, new_gid as u32, ctx).map(|_| 0)
}
/* TODO: Support Unlinkat using std_fs_call
Unlinkat => {
let path = unsafe { str::from_utf8_unchecked(payload) };
let flags = metadata.arg1; {
if !matches!(
self.handles.get(&id).ok_or(Error::new(EBADF))?,
Handle::SchemeRoot
) {
return Err(Error::new(EACCES));
}
}
let (_pid, uid, gid) = get_uid_gid_from_pid(&self.proc_creds_capability, ctx.pid)?;
self.remove_dentry(
path,
uid,
gid,
*flags as usize & syscall::AT_REMOVEDIR == syscall::AT_REMOVEDIR,
)
.map(|_| 0)
}
*/
_ => Err(Error::new(EOPNOTSUPP)),
}
}
}
impl Scheme {
pub fn on_close(&mut self, fd: usize) {
@@ -682,3 +734,32 @@ fn check_permissions(flags: usize, single_mode: u8) -> Result<()> {
}
Ok(())
}
fn get_uid_gid_from_pid(cap_fd: &libredox::Fd, target_pid: usize) -> Result<(u32, u32, u32)> {
let mut buffer = [0u8; mem::size_of::<libredox::protocol::ProcMeta>()];
let _ = libredox::call::get_proc_credentials(cap_fd.raw(), target_pid, &mut buffer).map_err(
|e| {
eprintln!(
"Failed to get process credentials for pid {}: {:?}",
target_pid, e
);
Error::new(EINVAL)
},
)?;
let mut cursor = 0;
let pid = read_u32(&buffer, cursor)?;
cursor += mem::size_of::<u32>() * 3;
let uid = read_u32(&buffer, cursor)?;
cursor += mem::size_of::<u32>() * 3;
let gid = read_u32(&buffer, cursor)?;
Ok((pid, uid, gid))
}
fn read_u32(buffer: &[u8], offset: usize) -> Result<u32> {
let bytes = buffer
.get(offset..offset + 4)
.and_then(|slice| slice.try_into().ok())
.ok_or_else(|| Error::new(EINVAL))?;
Ok(u32::from_le_bytes(bytes))
}
+4 -2
View File
@@ -14,7 +14,8 @@ pub const MODE_READ: u16 = 0o4;
use raw_cpuid::CpuId;
use redox_scheme::{
scheme::SchemeSync, CallerCtx, OpenResult, RequestKind, SignalBehavior, Socket,
scheme::{SchemeState, SchemeSync},
CallerCtx, OpenResult, RequestKind, SignalBehavior, Socket,
};
use syscall::data::Stat;
use syscall::flag::{EventFlags, O_CREAT, O_EXCL, O_RDONLY, O_RDWR, O_WRONLY};
@@ -467,6 +468,7 @@ impl SchemeSync for RandScheme {
fn daemon(daemon: daemon::SchemeDaemon) -> ! {
let socket = Socket::create().expect("randd: failed to create rand scheme");
let mut state = SchemeState::new();
let mut scheme = RandScheme::new();
let _ = daemon.ready_sync_scheme(&socket, &mut scheme);
@@ -479,7 +481,7 @@ fn daemon(daemon: daemon::SchemeDaemon) -> ! {
{
match request.kind() {
RequestKind::Call(call) => {
let response = call.handle_sync(&mut scheme);
let response = call.handle_sync(&mut scheme, &mut state);
socket
.write_response(response, SignalBehavior::Restart)
.expect("error writing packet");
+3 -2
View File
@@ -1,4 +1,4 @@
use redox_scheme::{RequestKind, SignalBehavior, Socket};
use redox_scheme::{scheme::SchemeState, RequestKind, SignalBehavior, Socket};
use scheme::ZeroScheme;
@@ -21,6 +21,7 @@ fn daemon(daemon: daemon::SchemeDaemon) -> ! {
};
let socket = Socket::create().expect("zerod: failed to create zero scheme");
let mut state = SchemeState::new();
let mut zero_scheme = ZeroScheme(ty);
let _ = daemon.ready_sync_scheme(&socket, &mut zero_scheme);
@@ -36,7 +37,7 @@ fn daemon(daemon: daemon::SchemeDaemon) -> ! {
};
match request.kind() {
RequestKind::Call(request) => {
let response = request.handle_sync(&mut zero_scheme);
let response = request.handle_sync(&mut zero_scheme, &mut state);
socket
.write_response(response, SignalBehavior::Restart)