Reach init with proc manager.

This commit is contained in:
4lDO2
2024-12-27 13:55:49 +01:00
parent b4a7992074
commit 3dbd606086
5 changed files with 61 additions and 42 deletions
Generated
+1
View File
@@ -20,6 +20,7 @@ version = "0.0.0"
dependencies = [
"hashbrown",
"linked_list_allocator",
"plain",
"redox-initfs",
"redox-path",
"redox-rt",
+1
View File
@@ -15,6 +15,7 @@ hashbrown = { version = "0.14", default-features = false, features = [
"ahash",
] }
linked_list_allocator = "0.10"
plain = "0.2"
redox-initfs = { git = "https://gitlab.redox-os.org/redox-os/redox-initfs.git", default-features = false }
redox_syscall = { version = "0.5.4", default-features = false }
redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" }
+28 -22
View File
@@ -7,6 +7,14 @@ use syscall::{Error, EINTR};
use redox_rt::proc::*;
pub fn main() -> ! {
let auth = FdGuard::new(
syscall::open("/scheme/kernel.proc/authority", O_CLOEXEC)
.expect("failed to get proc authority"),
);
let this_thr_fd =
FdGuard::new(syscall::dup(*auth, b"cur-context").expect("failed to open open_via_dup"));
let this_thr_fd = unsafe { redox_rt::initialize_freestanding(this_thr_fd) };
let envs = {
let mut env = [0_u8; 4096];
@@ -37,29 +45,27 @@ pub fn main() -> ! {
(*(core::ptr::addr_of!(__initfs_header) as *const redox_initfs::types::Header)).initfs_size
};
spawn("initfs daemon", move |write_fd| unsafe {
// Creating a reference to NULL is UB. Mask the UB for now using black_box.
// FIXME use a raw pointer and inline asm for reading instead for the initfs header.
let initfs_start = core::ptr::addr_of!(__initfs_header);
let initfs_length = initfs_length.get() as usize;
spawn(
"initfs daemon",
&auth,
&this_thr_fd,
move |write_fd| unsafe {
// Creating a reference to NULL is UB. Mask the UB for now using black_box.
// FIXME use a raw pointer and inline asm for reading instead for the initfs header.
let initfs_start = core::ptr::addr_of!(__initfs_header);
let initfs_length = initfs_length.get() as usize;
crate::initfs::run(
core::slice::from_raw_parts(initfs_start, initfs_length),
write_fd,
);
});
crate::initfs::run(
core::slice::from_raw_parts(initfs_start, initfs_length),
write_fd,
);
},
);
let auth = FdGuard::new(syscall::open("/scheme/kernel.proc/authority", O_CLOEXEC).expect("failed to get proc authority"));
spawn("process manager", |write_fd| {
spawn("process manager", &auth, &this_thr_fd, |write_fd| {
crate::procmngr::run(write_fd, &auth)
});
let this_thr_fd = FdGuard::new(
syscall::dup(*auth, b"cur-context").expect("failed to open open_via_dup"),
);
let (init_proc_fd, init_thr_fd) = unsafe {
redox_rt::proc::make_init(this_thr_fd)
};
let init_proc_fd = unsafe { redox_rt::proc::make_init() };
const CWD: &[u8] = b"/scheme/initfs";
const DEFAULT_SCHEME: &[u8] = b"initfs";
@@ -86,8 +92,8 @@ pub fn main() -> ! {
fexec_impl(
image_file,
this_thr_fd,
init_proc_fd,
init_thr_fd,
&memory,
path.as_bytes(),
[path],
@@ -101,13 +107,13 @@ pub fn main() -> ! {
unreachable!()
}
pub(crate) fn spawn(name: &str, inner: impl FnOnce(usize)) {
pub(crate) fn spawn(name: &str, auth: &FdGuard, this_thr_fd: &FdGuard, inner: impl FnOnce(usize)) {
let read = syscall::open("/scheme/pipe", O_CLOEXEC).expect("failed to open sync read pipe");
// The write pipe will not inherit O_CLOEXEC, but is closed by the daemon later.
let write = syscall::dup(read, b"write").expect("failed to open sync write pipe");
match fork_impl() {
match fork_impl(&ForkArgs::Init { this_thr_fd, auth }) {
Err(err) => {
panic!("Failed to fork in order to start {name}: {err}");
}
+31 -18
View File
@@ -1,8 +1,9 @@
use core::cell::RefCell;
use core::mem::size_of;
use alloc::rc::Rc;
use alloc::vec::Vec;
use alloc::vec;
use alloc::vec::Vec;
use hashbrown::hash_map::DefaultHashBuilder;
use hashbrown::{HashMap, HashSet};
@@ -13,7 +14,9 @@ use redox_scheme::{
};
use slab::Slab;
use syscall::schemev2::NewFdFlags;
use syscall::{Error, FobtainFdFlags, Result, EBADF, EBADFD, EEXIST, EINVAL, ENOENT, O_CLOEXEC, O_CREAT};
use syscall::{
Error, FobtainFdFlags, Result, EBADF, EBADFD, EEXIST, EINVAL, ENOENT, O_CLOEXEC, O_CREAT,
};
pub fn run(write_fd: usize, auth: &FdGuard) {
let socket = Socket::create("proc").expect("failed to open proc scheme socket");
@@ -157,9 +160,7 @@ impl<'a> ProcScheme<'a> {
self.processes.insert(
child_pid,
Process {
threads: vec! [Rc::new(RefCell::new(Thread {
fd: new_ctxt_fd,
}))],
threads: vec![Rc::new(RefCell::new(Thread { fd: new_ctxt_fd }))],
ppid: parent_pid,
pgid,
sid,
@@ -176,8 +177,7 @@ impl<'a> ProcScheme<'a> {
fn new_thread(&mut self, pid: ProcessId) -> Result<FdGuard> {
let proc = self.processes.get_mut(&pid).ok_or(Error::new(EBADFD))?;
let fd = todo!();
proc.threads
.push(Rc::new(RefCell::new(Thread { fd })));
proc.threads.push(Rc::new(RefCell::new(Thread { fd })));
Ok(fd)
}
}
@@ -188,22 +188,26 @@ impl Scheme for ProcScheme<'_> {
return Err(Error::new(EEXIST));
}
return Ok(OpenResult::ThisScheme {
number: self
.handles
.insert(Handle::Init),
number: self.handles.insert(Handle::Init),
flags: NewFdFlags::empty(),
});
}
Err(Error::new(ENOENT))
}
fn read(&mut self, id: usize, buf: &mut [u8], _offset: u64, _fcntl_flags: u32) -> Result<usize> {
fn read(
&mut self,
id: usize,
buf: &mut [u8],
_offset: u64,
_fcntl_flags: u32,
) -> Result<usize> {
match self.handles[id] {
Handle::Proc(pid) => {
let process = self.processes.get(&pid).ok_or(Error::new(EBADFD))?;
let metadata = ProcMeta {
pid: pid.into(),
pgid: process.pgid.into(),
ppid: process.ppid.into(),
pid: pid.0 as u32,
pgid: process.pgid.0 as u32,
ppid: process.ppid.0 as u32,
euid: process.euid,
egid: process.egid,
ruid: process.ruid,
@@ -211,6 +215,10 @@ impl Scheme for ProcScheme<'_> {
ens: process.ens,
rns: process.rns,
};
*buf.get_mut(..size_of::<ProcMeta>())
.and_then(|b| plain::from_mut_bytes(b).ok())
.ok_or(Error::new(EINVAL))? = metadata;
Ok(size_of::<ProcMeta>())
}
Handle::Init => return Err(Error::new(EBADF)),
}
@@ -224,16 +232,21 @@ impl Scheme for ProcScheme<'_> {
number: self.handles.insert(Handle::Proc(child_pid)),
flags: NewFdFlags::empty(),
})
},
}
b"new-thread" => Ok(OpenResult::OtherScheme {
fd: self.new_thread(pid)?.take(),
}),
w if w.starts_with("thread-") => {
let idx = core::str::from_utf8(&w["thread-".len()..]).ok().and_then(|s| s.parse::<usize>().ok()).ok_or(Error::new(EINVAL))?;
w if w.starts_with(b"thread-") => {
let idx = core::str::from_utf8(&w["thread-".len()..])
.ok()
.and_then(|s| s.parse::<usize>().ok())
.ok_or(Error::new(EINVAL))?;
let process = self.processes.get(&pid).ok_or(Error::new(EBADFD))?;
let thread = process.threads.get(idx).ok_or(Error::new(ENOENT))?.borrow();
return Ok(OpenResult::OtherScheme { fd: syscall::dup(*thread.fd, &[])? });
return Ok(OpenResult::OtherScheme {
fd: syscall::dup(*thread.fd, &[])?,
});
}
_ => return Err(Error::new(EINVAL)),
},
-2
View File
@@ -78,8 +78,6 @@ pub unsafe extern "C" fn start() -> ! {
)
.expect("mprotect failed for rest of memory");
redox_rt::initialize_freestanding();
// FIXME make the initfs read-only
crate::exec::main();