ptyd: accept ptmx as master open; strip init/daemon boot debug spam

This commit is contained in:
Red Bear OS
2026-07-15 21:38:39 +09:00
parent 194a77df11
commit 54e4c5751c
5 changed files with 9 additions and 65 deletions
-6
View File
@@ -107,18 +107,12 @@ impl SchemeDaemon {
/// Notify the process that the scheme daemon is ready to accept requests.
pub fn ready_with_fd(self, cap_fd: Fd) -> syscall::Result<()> {
let raw_fd = cap_fd.into_raw();
eprintln!(
"daemon: ready_with_fd write_pipe={} cap_fd={}",
self.write_pipe.as_raw_fd(),
raw_fd
);
let res = syscall::call_wo(
self.write_pipe.as_raw_fd() as usize,
&raw_fd.to_ne_bytes(),
syscall::CallFlags::FD,
&[],
);
eprintln!("daemon: ready_with_fd call_wo result={:?}", res);
res?;
Ok(())
}
-19
View File
@@ -104,14 +104,9 @@ fn switch_root(unit_store: &mut UnitStore, config: &mut InitConfig, prefix: &Pat
}
fn main() {
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
use std::io::Write;
let _ = writeln!(f, "INIT: main() entered");
}
let mut init_config = InitConfig::new();
let mut unit_store = UnitStore::new();
let mut scheduler = Scheduler::new();
eprintln!("INIT: about to switch_root (initfs)");
switch_root(
&mut unit_store,
@@ -171,17 +166,7 @@ fn main() {
}
};
eprintln!("INIT: starting /usr scheduler step");
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
use std::io::Write;
let _ = writeln!(f, "BEFORE_STEP");
}
scheduler.step(&mut unit_store, &mut init_config);
eprintln!("INIT: waitpid loop");
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
use std::io::Write;
let _ = writeln!(f, "AFTER_STEP");
}
// Enter a null namespace containing only memory and pipe schemes. This
// limits what daemons can access if they crash or misbehave. For the
@@ -192,10 +177,6 @@ fn main() {
if let Err(e) = libredox::call::setrens(0, 0) {
eprintln!("INIT: warning, could not enter null namespace: {e}");
eprintln!("INIT: continuing with full scheme set");
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
use std::io::Write;
let _ = writeln!(f, "INIT: setrens warning: {e}");
}
}
loop {
-11
View File
@@ -1,5 +1,4 @@
use std::collections::{BTreeMap, VecDeque};
use std::io::Write;
use crate::InitConfig;
use crate::color::{init_debug, init_error, init_info, status_ok, status_skip};
@@ -60,16 +59,12 @@ impl Scheduler {
let mut defer_count: BTreeMap<String, usize> = BTreeMap::new();
'a: loop {
let Some(job) = self.pending.pop_front() else {
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
let _ = writeln!(f, "STEP_DONE");
}
return;
};
match job.kind {
JobKind::Start => {
let unit = unit_store.unit_mut(&job.unit);
eprintln!("init: DBG job={}", job.unit.0);
let mut blocked = false;
for dep in &unit.info.requires_weak {
@@ -89,15 +84,9 @@ impl Scheduler {
self.pending.push_back(job);
continue 'a;
}
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
let _ = writeln!(f, "FORCE {}", job.unit.0);
}
}
run(unit, init_config);
if let Ok(mut f) = std::fs::OpenOptions::new().write(true).open("/scheme/debug/no-preserve") {
let _ = writeln!(f, "RAN {}", unit.id.0);
}
}
}
}
+1 -28
View File
@@ -56,8 +56,6 @@ fn create_pipe() -> io::Result<(File, OwnedFd)> {
impl Service {
pub fn spawn(&self, base_envs: &BTreeMap<String, OsString>) {
eprintln!("init: service {} type={:?}", self.cmd, self.type_);
let _ = io::stderr().flush();
let mut command = Command::new(&self.cmd);
command.args(self.args.iter().map(|arg| subst_env(arg)));
command.env_clear();
@@ -70,30 +68,18 @@ impl Service {
let (mut read_pipe, write_pipe) = create_pipe()
.unwrap_or_else(|e| panic!("pipe() failed in service.spawn for {}: {}", self.cmd, e));
eprintln!("init: {} pipe created read_pipe={}", self.cmd, read_pipe.as_raw_fd());
let _ = io::stderr().flush();
unsafe { pass_fd(&mut command, "INIT_NOTIFY", write_pipe.into()) };
eprintln!("init: {} pass_fd done", self.cmd);
let _ = io::stderr().flush();
let mut child = match command.spawn() {
Ok(child) => {
eprintln!("init: {} spawned pid=??", self.cmd);
let _ = io::stderr().flush();
child
},
Ok(child) => child,
Err(err) => {
status_fail(&format!("failed to execute {:?}: {}", command, err));
return;
}
};
eprintln!("init: {} entering match type={:?}", self.cmd, self.type_);
let _ = io::stderr().flush();
match &self.type_ {
ServiceType::Notify => {
eprintln!("init: {} is Notify, waiting for byte", self.cmd);
let _ = io::stderr().flush();
match read_pipe.read_exact(&mut [0]) {
Ok(()) => {}
Err(err) if err.kind() == io::ErrorKind::UnexpectedEof => {
@@ -105,17 +91,8 @@ impl Service {
}
}
ServiceType::Scheme(scheme) => {
eprintln!("init: SCHEME {} waiting for fd on read_pipe={}", self.cmd, read_pipe.as_raw_fd());
let _ = io::stderr().flush();
init_warn(&format!(
"init: waiting for scheme fd from {:?}, read_pipe={}",
command,
read_pipe.as_raw_fd()
));
let mut new_fd = usize::MAX;
loop {
eprintln!("init: calling call_ro for {}", self.cmd);
let _ = io::stderr().flush();
match syscall::call_ro(
read_pipe.as_raw_fd() as usize,
unsafe { plain::as_mut_bytes(&mut new_fd) },
@@ -130,10 +107,6 @@ impl Service {
return;
}
Ok(1) => {
init_warn(&format!(
"init: received scheme fd {} from {:?}, registering as {}",
new_fd, command, scheme
));
break;
}
Ok(n) => {
+8 -1
View File
@@ -72,7 +72,14 @@ impl SchemeSync for PtyScheme {
let id = self.next_id;
self.next_id += 1;
if path.is_empty() {
// The master clone device is opened either as the bare scheme root
// ("/scheme/pty", empty reference) or via the conventional "ptmx"
// name ("/scheme/pty/ptmx", which is what userutils' getty uses).
// Numeric references ("/scheme/pty/<n>") are subterminals of an
// existing master. Without the "ptmx" case, getty's master open
// hit `"ptmx".parse::<usize>()` -> EINVAL and panicked
// ("failed to create PTY: Invalid argument").
if path.is_empty() || path == "ptmx" {
let pty = Rc::new(RefCell::new(Pty::new(id)));
self.handles.insert(
id,