From c462bd9d3115868bf147949f1f4dc5ceeee31acc Mon Sep 17 00:00:00 2001 From: mozempk Date: Thu, 23 Apr 2026 08:01:11 +0200 Subject: [PATCH] fix: nix profile circular symlink, mdns hang, deprecated install command - first-login.sh: remove nix-env --switch-profile (caused .nix-profile-> .nix-profile circular symlink, breaking all nix profile commands and causing ELOOP on any exec via nix PATH including xz/tar/node) - first-login.sh: add circular symlink guard before nix profile add - first-login.sh: nix profile install -> nix profile add (deprecated alias) - live-setup.sh: strip mdns from nsswitch.conf hosts line at boot (no libnss_mdns/Avahi in live; caused first-login DNS hang) - docs/LIVE_ISO.md: document all three issues and their fixes --- docs/LIVE_ISO.md | 22 +++++++++++++++++++++- installer/first-login.sh | 18 +++++++++++++----- iso/build-live-iso.sh | 9 +++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/docs/LIVE_ISO.md b/docs/LIVE_ISO.md index f86b0e7..292eb6d 100644 --- a/docs/LIVE_ISO.md +++ b/docs/LIVE_ISO.md @@ -180,7 +180,27 @@ Output: `out/void-live-stable.iso` (~2.9 GB) --- -## QEMU Testing +## Known Issues & Fixes + +### `nix-env --switch-profile "$HOME/.nix-profile"` creates a circular symlink +**Symptom:** `error: filesystem error: status: Too many levels of symbolic links [/home/live/.nix-profile/manifest.json]` and `tar: xz: Cannot exec: Too many levels of symbolic links` (all binaries fail to exec via nix PATH). +**Cause:** Passing `$HOME/.nix-profile` as the target to `nix-env --switch-profile` creates `~/.nix-profile -> .nix-profile` — a symlink that points to itself. This corrupts the nix profile directory and causes ELOOP on any file lookup under that path. +**Fix:** Do not call `nix-env --switch-profile` at all when using `nix profile add` (new-style commands). Let `nix profile add` initialise the profile automatically. The first-login script also contains a guard that detects and removes the circular symlink before proceeding. + +### `nix profile install` is deprecated +Use `nix profile add` instead. `nix profile install` is an alias that emits a warning and will be removed in a future Nix version. + +### DNS hang in live environment (nsswitch `mdns` without Avahi) +**Symptom:** `getent hosts github.com` hangs indefinitely; `first-login.sh` stuck at "starting". +**Cause:** `/etc/nsswitch.conf` includes `mdns` in the `hosts:` line. On Void Linux, `libnss_mdns.so.2` may not be present, and even if it is, the Avahi daemon is not running in the live session. glibc waits for Avahi's D-Bus socket before timing out. +**Fix:** `live-setup.sh` runs at boot and removes `mdns` from `nsswitch.conf`: `sed -i '/^hosts:/s/mdns[^ ]* *//g' /etc/nsswitch.conf`. This is safe on real hardware (NetworkManager provides proper DNS via DHCP). + +### QEMU internal DNS (10.0.2.3) unreliable +**Symptom:** Even after removing `mdns`, DNS queries to QEMU's built-in resolver (10.0.2.3) time out. +**Cause:** QEMU's user-mode DNS proxy may not forward queries correctly depending on the host network configuration. +**Workaround for QEMU testing:** `echo nameserver 8.8.8.8 > /etc/resolv.conf`. This is not needed on real hardware. + +--- ```bash cp /usr/share/OVMF/OVMF_VARS.fd out/OVMF_VARS.live.fd diff --git a/installer/first-login.sh b/installer/first-login.sh index 70857a0..4ecf5f9 100644 --- a/installer/first-login.sh +++ b/installer/first-login.sh @@ -43,9 +43,16 @@ if [[ -r "$NIX_PACKAGES_FILE" ]] && command -v nix >/dev/null 2>&1; then [[ -r "$f" ]] && . "$f" done - # Initialise per-user nix profile if needed. - if [[ ! -d "$HOME/.nix-profile" ]]; then - nix-env --switch-profile "$HOME/.nix-profile" 2>/dev/null || true + # Guard: nix-env --switch-profile creates a circular symlink when given + # ~/.nix-profile as the target (it points to itself). Remove it so + # 'nix profile add' can initialise a clean profile. + if [[ -L "$HOME/.nix-profile" ]]; then + _target=$(readlink "$HOME/.nix-profile") + if [[ "$_target" == ".nix-profile" || "$_target" == "$HOME/.nix-profile" ]]; then + echo " removing circular .nix-profile symlink" + rm -f "$HOME/.nix-profile" + fi + unset _target fi # D-Bus session is available when autostarted from Cinnamon. @@ -58,8 +65,9 @@ if [[ -r "$NIX_PACKAGES_FILE" ]] && command -v nix >/dev/null 2>&1; then mapfile -t pkgs < <(grep -vE '^\s*(#|$)' "$NIX_PACKAGES_FILE") if [[ ${#pkgs[@]} -gt 0 ]]; then echo " packages: ${pkgs[*]}" - nix profile install --impure "${pkgs[@]}" 2>&1 || { - echo "!! nix profile install failed (partial install may have succeeded)"; } + # 'nix profile install' is deprecated as of nix 2.x — use 'nix profile add' + nix profile add --impure "${pkgs[@]}" 2>&1 || { + echo "!! nix profile add failed (partial install may have succeeded)"; } fi fi diff --git a/iso/build-live-iso.sh b/iso/build-live-iso.sh index 12ba410..421c650 100755 --- a/iso/build-live-iso.sh +++ b/iso/build-live-iso.sh @@ -121,6 +121,15 @@ NIXSH echo "live-setup: nix daemon mode configured (trusted-users = $LIVE_USER)" fi +# ── nsswitch: remove mdns (library absent on Void; no Avahi daemon) ────── +# 'mdns' in nsswitch.conf without libnss_mdns causes hangs on every DNS +# lookup because glibc spins waiting for Avahi's socket. Remove it so +# standard DNS resolution is used directly. +if [ -f /etc/nsswitch.conf ]; then + sed -i '/^hosts:/s/mdns[^ ]* *//g' /etc/nsswitch.conf + echo "live-setup: removed mdns from nsswitch.conf (hosts line)" +fi + # ── D-Bus session socket for the live user's login session ─────────────── # dbus-launch is called by lightdm-session / Xsession automatically. # Ensure dbus system bus is accessible (needed by nix and Cinnamon).