ptyd: accept ptmx as master open; strip init/daemon boot debug spam
This commit is contained in:
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user