diag(base): trace fd transfer in init, daemon, and logd

Add diagnostics to pin down where the INIT_NOTIFY fd handoff hangs:
- init/src/service.rs: log read_pipe fd and call_ro results
- daemon/src/lib.rs: log cap_fd, write_pipe, and call_wo result
- logd/src/main.rs: explicit ready_sync_scheme result and setrens fallback

These are temporary diagnostics for the boot-hang investigation.
This commit is contained in:
Red Bear OS
2026-07-14 09:16:46 +09:00
parent 1e341ff782
commit 0a358aa05f
3 changed files with 62 additions and 17 deletions
+11 -3
View File
@@ -106,12 +106,20 @@ 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<()> {
syscall::call_wo(
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,
&cap_fd.into_raw().to_ne_bytes(),
&raw_fd.to_ne_bytes(),
syscall::CallFlags::FD,
&[],
)?;
);
eprintln!("daemon: ready_with_fd call_wo result={:?}", res);
res?;
Ok(())
}
+43 -12
View File
@@ -1,11 +1,11 @@
use std::collections::{BTreeMap, BTreeSet};
use std::ffi::OsString;
use std::fs::File;
use std::io::Read;
use std::io::{self, Read, Write};
use std::os::fd::{AsRawFd, FromRawFd, OwnedFd};
use std::os::unix::process::CommandExt;
use std::process::Command;
use std::{env, io};
use std::env;
use serde::Deserialize;
@@ -49,6 +49,8 @@ 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();
@@ -61,29 +63,52 @@ 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) => child,
Ok(child) => {
eprintln!("init: {} spawned pid=??", self.cmd);
let _ = io::stderr().flush();
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 => match read_pipe.read_exact(&mut [0]) {
Ok(()) => {}
Err(err) if err.kind() == io::ErrorKind::UnexpectedEof => {
init_warn(&format!("{:?} exited without notifying readiness", command));
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 => {
init_warn(&format!("{:?} exited without notifying readiness", command));
}
Err(err) => {
init_error(&format!("failed to wait for {:?}: {}", command, err));
}
}
Err(err) => {
init_error(&format!("failed to wait for {:?}: {}", command, err));
}
},
}
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) },
@@ -97,7 +122,13 @@ impl Service {
init_warn(&format!("{:?} exited without notifying readiness", command));
return;
}
Ok(1) => break,
Ok(1) => {
init_warn(&format!(
"init: received scheme fd {} from {:?}, registering as {}",
new_fd, command, scheme
));
break;
}
Ok(n) => {
init_error(&format!("incorrect amount of fds {} returned", n));
return;
+8 -2
View File
@@ -11,9 +11,15 @@ fn daemon(daemon: daemon::SchemeDaemon) -> ! {
let mut scheme = LogScheme::new(&socket);
let handler = Blocking::new(&socket, 16);
let _ = daemon.ready_sync_scheme(&socket, &mut scheme);
match daemon.ready_sync_scheme(&socket, &mut scheme) {
Ok(()) => eprintln!("logd: ready_sync_scheme succeeded"),
Err(err) => eprintln!("logd: ready_sync_scheme failed: {err}"),
}
libredox::call::setrens(0, 0).expect("logd: failed to enter null namespace");
match libredox::call::setrens(0, 0) {
Ok(_) => {}
Err(err) => eprintln!("logd: warning: failed to enter null namespace: {err}"),
}
handler
.process_requests_blocking(scheme)