WIP: write skeleton for fork, new-thread

This commit is contained in:
4lDO2
2024-12-26 16:19:12 +01:00
parent eecd046709
commit 9f0ddc83f4
5 changed files with 167 additions and 36 deletions
+2
View File
@@ -12,6 +12,7 @@ crate-type = ["staticlib"]
[dependencies]
hashbrown = { version = "0.14", default-features = false, features = [
"inline-more",
"ahash",
] }
linked_list_allocator = "0.10"
redox-initfs = { git = "https://gitlab.redox-os.org/redox-os/redox-initfs.git", default-features = false }
@@ -20,6 +21,7 @@ redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
#redox-rt = { git = "https://gitlab.redox-os.org/redox-os/relibc", default-features = false }
redox-rt = { git = "https://gitlab.redox-os.org/4lDO2/relibc.git", branch = "userspace_proc", default-features = false }
redox-path = "0.3.1"
slab = { version = "0.4.9", default-features = false }
[profile.release]
panic = "abort"
+4 -8
View File
@@ -1,9 +1,5 @@
use core::mem;
use syscall::{
data::Map,
flag::MapFlags,
number::SYS_FMAP,
};
use syscall::{data::Map, flag::MapFlags, number::SYS_FMAP};
pub const USERMODE_END: usize = 0x0000_8000_0000_0000;
pub const STACK_START: usize = USERMODE_END - STACK_SIZE;
@@ -13,9 +9,9 @@ static MAP: Map = Map {
offset: 0,
size: STACK_SIZE,
flags: MapFlags::PROT_READ
.union(MapFlags::PROT_WRITE)
.union(MapFlags::MAP_PRIVATE)
.union(MapFlags::MAP_FIXED_NOREPLACE),
.union(MapFlags::PROT_WRITE)
.union(MapFlags::MAP_PRIVATE)
.union(MapFlags::MAP_FIXED_NOREPLACE),
address: STACK_START, // highest possible user address
};
+7 -4
View File
@@ -49,7 +49,9 @@ pub fn main() -> ! {
);
});
spawn("process manager", move |write_fd| crate::procmngr::run(write_fd));
spawn("process manager", move |write_fd| {
crate::procmngr::run(write_fd)
});
const CWD: &[u8] = b"/scheme/initfs";
const DEFAULT_SCHEME: &[u8] = b"initfs";
@@ -73,12 +75,13 @@ pub fn main() -> ! {
let image_file = FdGuard::new(syscall::open(path, O_RDONLY).expect("failed to open init"));
let open_via_dup = FdGuard::new(
syscall::open("/scheme/thisproc/current", 0)
.expect("failed to open open_via_dup"),
syscall::open("/scheme/thisproc/current", 0).expect("failed to open open_via_dup"),
);
let memory = FdGuard::new(syscall::open("/scheme/memory", 0).expect("failed to open memory"));
redox_rt::proc::make_init();
unsafe {
redox_rt::proc::make_init();
}
fexec_impl(
image_file,
+5 -10
View File
@@ -9,14 +9,9 @@ use hashbrown::HashMap;
use redox_initfs::{types::Timespec, InitFs, Inode, InodeDir, InodeKind, InodeStruct};
use redox_path::canonicalize_to_standard;
use redox_scheme::CallerCtx;
use redox_scheme::OpenResult;
use redox_scheme::RequestKind;
use redox_scheme::SchemeMut;
use redox_scheme::{CallerCtx, OpenResult, RequestKind, Scheme};
use redox_scheme::SignalBehavior;
use redox_scheme::Socket;
use redox_scheme::V2;
use redox_scheme::{SignalBehavior, Socket};
use syscall::data::Stat;
use syscall::dirent::DirEntry;
use syscall::dirent::DirentBuf;
@@ -93,7 +88,7 @@ fn inode_len(inode: InodeStruct<'static>) -> Result<usize> {
})
}
impl SchemeMut for InitFsScheme {
impl Scheme for InitFsScheme {
fn xopen(&mut self, path: &str, flags: usize, _ctx: &CallerCtx) -> Result<OpenResult> {
let mut components = path
// trim leading and trailing slash
@@ -317,7 +312,7 @@ impl SchemeMut for InitFsScheme {
pub fn run(bytes: &'static [u8], sync_pipe: usize) -> ! {
let mut scheme = InitFsScheme::new(bytes);
let socket = Socket::<V2>::create("initfs").expect("failed to open initfs scheme socket");
let socket = Socket::create("initfs").expect("failed to open initfs scheme socket");
let _ = syscall::write(sync_pipe, &[0]);
let _ = syscall::close(sync_pipe);
@@ -332,7 +327,7 @@ pub fn run(bytes: &'static [u8], sync_pipe: usize) -> ! {
}) else {
continue;
};
let resp = req.handle_scheme_mut(&mut scheme);
let resp = req.handle_scheme(&mut scheme);
if !socket
.write_response(resp, SignalBehavior::Restart)
+149 -14
View File
@@ -1,14 +1,21 @@
use core::cell::RefCell;
use alloc::rc::Rc;
use alloc::vec::Vec;
use alloc::vec;
use hashbrown::hash_map::DefaultHashBuilder;
use hashbrown::{HashMap, HashSet};
use redox_rt::proc::FdGuard;
use redox_scheme::{CallerCtx, OpenResult, RequestKind, SchemeMut, SignalBehavior, Socket, V2};
use syscall::{Result, O_CREAT};
use redox_scheme::{
CallerCtx, OpenResult, RequestKind, Response, Scheme, SendFdRequest, SignalBehavior, Socket,
};
use slab::Slab;
use syscall::schemev2::NewFdFlags;
use syscall::{Error, FobtainFdFlags, Result, EBADF, EBADFD, EEXIST, EINVAL, ENOENT, O_CREAT};
pub fn run(write_fd: usize) {
let socket = Socket::<V2>::create("proc").expect("failed to open proc scheme socket");
let socket = Socket::create("proc").expect("failed to open proc scheme socket");
let mut scheme = ProcScheme::new();
let _ = syscall::write(1, b"process manager started\n").unwrap();
@@ -16,16 +23,17 @@ pub fn run(write_fd: usize) {
let _ = syscall::close(write_fd);
loop {
let RequestKind::Call(req) = (match socket
let Some(req) = socket
.next_request(SignalBehavior::Restart)
.expect("bootstrap: failed to read scheme request from kernel")
{
Some(req) => req.kind(),
None => break,
}) else {
else {
continue;
};
let resp = req.handle_scheme_mut(&mut scheme);
let resp = match req.kind() {
RequestKind::Call(req) => req.handle_scheme(&mut scheme),
RequestKind::SendFd(req) => scheme.on_sendfd(&socket, &req),
_ => continue,
};
if !socket
.write_response(resp, SignalBehavior::Restart)
@@ -43,6 +51,13 @@ struct Process {
ppid: ProcessId,
pgid: ProcessId,
sid: ProcessId,
ruid: u32,
euid: u32,
rgid: u32,
egid: u32,
rns: u32,
ens: u32,
}
struct Thread {
fd: FdGuard,
@@ -51,22 +66,142 @@ struct Thread {
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
struct ProcessId(usize);
const INIT_PID: ProcessId = ProcessId(1);
struct ProcScheme {
processes: HashMap<ProcessId, Process, DefaultHashBuilder>,
process_groups: HashSet<ProcessId, DefaultHashBuilder>,
sessions: HashSet<ProcessId, DefaultHashBuilder>,
handles: Slab<Handle>,
init_claimed: bool,
next_id: ProcessId,
}
enum Handle {
Init,
Proc(ProcessId),
}
impl ProcScheme {
pub fn new() -> ProcScheme {
ProcScheme {
processes: HashMap::new(),
process_groups: HashSet::new(),
sessions: HashSet::new(),
handles: Slab::new(),
init_claimed: false,
next_id: ProcessId(2),
}
}
fn new_id(&mut self) -> ProcessId {
let id = self.next_id;
self.next_id.0 += 1;
id
}
fn on_sendfd(&mut self, socket: &Socket, req: &SendFdRequest) -> Response {
match self.handles[req.id()] {
ref mut st @ Handle::Init => {
let mut fd_out = usize::MAX;
if let Err(e) = req.obtain_fd(socket, FobtainFdFlags::empty(), Err(&mut fd_out)) {
return Response::for_sendfd(&req, Err(e));
};
let thread = Rc::new(RefCell::new(Thread {
fd: FdGuard::new(fd_out),
}));
self.processes.insert(
INIT_PID,
Process {
threads: vec![thread],
ppid: INIT_PID,
sid: INIT_PID,
pgid: INIT_PID,
ruid: 0,
euid: 0,
rgid: 0,
egid: 0,
rns: 1,
ens: 1,
},
);
self.process_groups.insert(INIT_PID);
self.sessions.insert(INIT_PID);
*st = Handle::Proc(INIT_PID);
Response::for_sendfd(&req, Ok(0))
}
_ => Response::for_sendfd(&req, Err(Error::new(EBADF))),
}
}
fn fork(&mut self, parent_pid: ProcessId) -> Result<ProcessId> {
let child_pid = self.new_id();
let Process {
pgid,
sid,
euid,
ruid,
egid,
rgid,
ens,
rns,
..
} = *self.processes.get(&parent_pid).ok_or(Error::new(EBADFD))?;
self.processes.insert(
child_pid,
Process {
threads: Vec::new(),
ppid: parent_pid,
pgid,
sid,
ruid,
rgid,
euid,
egid,
rns,
ens,
},
);
Ok(child_pid)
}
fn new_thread(&mut self, pid: ProcessId) -> Result<FdGuard> {
let proc = self.processes.get_mut(&pid).ok_or(Error::new(EBADFD))?;
proc.threads
.push(Rc::new(RefCell::new(Thread { fd: todo!() })));
}
}
impl Scheme for ProcScheme {
fn xopen(&mut self, path: &str, flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
if path == "init" {
if core::mem::replace(&mut self.init_claimed, true) {
return Err(Error::new(EEXIST));
}
return Ok(OpenResult::ThisScheme {
number: self
.handles
.insert(Handle::Init),
flags: NewFdFlags::empty(),
});
}
Err(Error::new(ENOENT))
}
fn xdup(&mut self, old_id: usize, buf: &[u8], ctx: &CallerCtx) -> Result<OpenResult> {
match self.handles[old_id] {
Handle::Proc(pid) => match buf {
b"fork" => {
let child_pid = self.fork(pid)?;
Ok(OpenResult::ThisScheme {
number: self.handles.insert(Handle::Proc(child_pid)),
flags: NewFdFlags::empty(),
})
},
b"new-thread" => Ok(OpenResult::OtherScheme {
fd: self.new_thread(pid)?.take(),
}),
_ => return Err(Error::new(EINVAL)),
},
Handle::Init => Err(Error::new(EBADF)),
}
}
}
impl SchemeMut for ProcScheme {
fn xopen(&mut self, path: &str, flags: usize, ctx: &CallerCtx) -> Result<OpenResult> {
}
}