···46464747By default, some units are filtered from the outputs to make it less spammy.
4848This can be disabled for development or testing by setting the environment variable
4949-`STC_DISPLAY_ALL_UNITS=1`
4949+`STC_DISPLAY_ALL_UNITS=1`.
5050+5151+More detailed output can be displayed by setting `STC_DEBUG=1`.
50525153Most of these actions are either self-explaining but some of them have to do
5254with our units or the activation script. For this reason, these topics are
···123123// Allow for this switch-to-configuration to remain consistent with the perl implementation.
124124// Perl's "die" uses errno to set the exit code: https://perldoc.perl.org/perlvar#%24%21
125125fn die() -> ! {
126126- std::process::exit(std::io::Error::last_os_error().raw_os_error().unwrap_or(1));
126126+ let code = match std::io::Error::last_os_error().raw_os_error().unwrap_or(1) {
127127+ // Ensure that even if errno did not point to a helpful error code, we still have a
128128+ // non-zero exit code
129129+ 0 => 1,
130130+ other => other,
131131+ };
132132+133133+ std::process::exit(code);
127134}
128135129136fn parse_os_release() -> Result<HashMap<String, String>> {
···259266 &unit_file_content,
260267 ParseOption {
261268 enabled_quote: true,
269269+ enabled_indented_mutiline_value: false,
270270+ enabled_preserve_key_leading_whitespace: false,
262271 // Allow for escaped characters that won't get interpreted by the INI parser. These
263272 // often show up in systemd unit files device/mount/swap unit names (e.g. dev-disk-by\x2dlabel-root.device).
264273 enabled_escape: false,
···907916 submitted_jobs: &Rc<RefCell<HashMap<dbus::Path<'static>, Job>>>,
908917) {
909918 while !submitted_jobs.borrow().is_empty() {
919919+ log::debug!(
920920+ "waiting for submitted jobs to finish, still have {} job(s)",
921921+ submitted_jobs.borrow().len()
922922+ );
910923 _ = conn.process(Duration::from_millis(500));
911924 }
912925}
···959972 .restart_unit("nixos-activation.service", "replace")
960973 .context("Failed to restart nixos-activation.service")?;
961974975975+ log::debug!("waiting for nixos activation to finish");
962976 while !*nixos_activation_done.borrow() {
963977 _ = dbus_conn
964978 .process(Duration::from_secs(500))
···98710019881002/// Performs switch-to-configuration functionality for the entire system
9891003fn do_system_switch(action: Action) -> anyhow::Result<()> {
10041004+ log::debug!("Performing system switch");
10051005+9901006 let out = PathBuf::from(required_env("OUT")?);
9911007 let toplevel = PathBuf::from(required_env("TOPLEVEL")?);
9921008 let distro_id = required_env("DISTRO_ID")?;
···9941010 let install_bootloader = required_env("INSTALL_BOOTLOADER")?;
9951011 let locale_archive = required_env("LOCALE_ARCHIVE")?;
9961012 let new_systemd = PathBuf::from(required_env("SYSTEMD")?);
10131013+ let log_level = if std::env::var("STC_DEBUG").is_ok() {
10141014+ LevelFilter::Debug
10151015+ } else {
10161016+ LevelFilter::Info
10171017+ };
99710189981019 let action = ACTION.get_or_init(|| action);
10201020+ log::debug!("Using action {:?}", action);
999102110001022 // The action that is to be performed (like switch, boot, test, dry-activate) Also exposed via
10011023 // environment variable from now on
···10271049 std::fs::set_permissions("/run/nixos", perms)
10281050 .context("Failed to set permissions on /run/nixos directory")?;
1029105110521052+ log::debug!("Creating lock file /run/nixos/switch-to-configuration.lock");
10301053 let Ok(lock) = std::fs::OpenOptions::new()
10311054 .append(true)
10321055 .create(true)
···10361059 die();
10371060 };
1038106110621062+ log::debug!("Acquiring lock on file /run/nixos/switch-to-configuration.lock");
10391063 let Ok(_lock) = Flock::lock(lock, FlockArg::LockExclusiveNonblock) else {
10401064 eprintln!("Could not acquire lock");
10411065 die();
10421066 };
1043106710441044- if syslog::init(Facility::LOG_USER, LevelFilter::Debug, Some("nixos")).is_err() {
10681068+ if syslog::init(Facility::LOG_USER, log_level, Some("nixos")).is_err() {
10451069 bail!("Failed to initialize logger");
10461070 }
10471071···10511075 != "1"
10521076 {
10531077 do_pre_switch_check(&pre_switch_check, &toplevel, action)?;
10781078+ log::debug!("Done performing pre-switch checks");
10541079 }
1055108010561081 if *action == Action::Check {
···10601085 // Install or update the bootloader.
10611086 if matches!(action, Action::Switch | Action::Boot) {
10621087 do_install_bootloader(&install_bootloader, &toplevel)?;
10881088+ log::debug!("Done performing bootloader installation");
10631089 }
1064109010651091 // Just in case the new configuration hangs the system, do a sync now.
···16401666 eprintln!("restarting systemd...");
16411667 _ = systemd.reexecute(); // we don't get a dbus reply here
1642166816691669+ log::debug!("waiting for systemd restart to finish");
16431670 while !*systemd_reload_status.borrow() {
16441671 _ = dbus_conn
16451672 .process(Duration::from_millis(500))
···1654168116551682 // Make systemd reload its units.
16561683 _ = systemd.reload(); // we don't get a dbus reply here
16841684+ log::debug!("waiting for systemd reload to finish");
16571685 while !*systemd_reload_status.borrow() {
16581686 _ = dbus_conn
16591687 .process(Duration::from_millis(500))
···16901718 .canonicalize()
16911719 .context("Failed to get full path to /proc/self/exe")?;
1692172017211721+ log::debug!("Performing user switch for {name}");
16931722 std::process::Command::new(&myself)
16941723 .uid(uid)
16951724 .gid(gid)
···18651894 //
18661895 // Wait for events from systemd to settle. process() will return true if we have received any
18671896 // messages on the bus.
18681868- while dbus_conn
18691869- .process(Duration::from_millis(250))
18701870- .unwrap_or_default()
18711871- {}
18971897+ let mut waited = Duration::from_millis(0);
18981898+ let wait_interval = Duration::from_millis(250);
18991899+ let max_wait = Duration::from_secs(90);
19001900+ log::debug!("waiting for systemd events to settle");
19011901+ while dbus_conn.process(wait_interval).unwrap_or_default() {
19021902+ waited += wait_interval;
19031903+ if waited >= max_wait {
19041904+ log::debug!("timed out waiting systemd events to settle");
19051905+ break;
19061906+ }
19071907+ }
1872190818731909 let new_active_units = get_active_units(&systemd)?;
18741910