From 9dae3cda91058ef58af02521acade05cc37f9fb9 Mon Sep 17 00:00:00 2001 From: Red Bear OS Date: Thu, 16 Jul 2026 09:29:24 +0900 Subject: [PATCH] init: try prefix then / for post-switchroot CWD (/usr is not a chdir target) --- init/src/main.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/init/src/main.rs b/init/src/main.rs index 4f646d042d..e99c584b74 100644 --- a/init/src/main.rs +++ b/init/src/main.rs @@ -54,19 +54,20 @@ impl InitConfig { fn switch_root(unit_store: &mut UnitStore, config: &mut InitConfig, prefix: &Path, etcdir: &Path) { status_ok(&format!("switchroot to {} {}", prefix.display(), etcdir.display())); - // Point init's working directory at the new root. There is no real chroot - // in Redox, so without this init's CWD stays unset and every daemon spawned - // after the switch inherits an invalid CWD (via AT_REDOX_CWD_FD). That made - // getcwd() fail in /usr binaries — e.g. the 00_base-env `zsh -c` setup - // service printed "zsh: Failed to get current directory: path invalid" and - // then HUNG, so init (which waits on that oneshot) never reached the login - // stack (ptyd/getty/login). Establishing a valid CWD here fixes both. - if let Err(err) = std::env::set_current_dir(prefix) { - init_warn(&format!( - "failed to chdir to new root {}: {}", - prefix.display(), - err - )); + // Point init's working directory at a valid directory in the new root so + // daemons spawned afterwards don't inherit an invalid CWD (via + // AT_REDOX_CWD_FD). Without this, getcwd() fails in /usr binaries — e.g. + // the 00_base-env `zsh -c` setup printed "zsh: Failed to get current + // directory: path invalid" and then hung, so init (which waits on that + // oneshot) never reached the login stack. The switch is logical (no + // chroot) and `prefix` (e.g. "/usr") is not itself a directory, so try the + // plausible roots in order and keep the first that works. + let cwd_candidates = [prefix.to_path_buf(), std::path::PathBuf::from("/")]; + if !cwd_candidates + .iter() + .any(|cand| std::env::set_current_dir(cand).is_ok()) + { + init_warn("failed to establish a valid working directory after switch_root"); } config