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
This commit is contained in:
mozempk
2026-04-23 08:01:11 +02:00
parent 5cd9b496fd
commit c462bd9d31
3 changed files with 43 additions and 6 deletions

View File

@@ -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 ```bash
cp /usr/share/OVMF/OVMF_VARS.fd out/OVMF_VARS.live.fd cp /usr/share/OVMF/OVMF_VARS.fd out/OVMF_VARS.live.fd

View File

@@ -43,9 +43,16 @@ if [[ -r "$NIX_PACKAGES_FILE" ]] && command -v nix >/dev/null 2>&1; then
[[ -r "$f" ]] && . "$f" [[ -r "$f" ]] && . "$f"
done done
# Initialise per-user nix profile if needed. # Guard: nix-env --switch-profile creates a circular symlink when given
if [[ ! -d "$HOME/.nix-profile" ]]; then # ~/.nix-profile as the target (it points to itself). Remove it so
nix-env --switch-profile "$HOME/.nix-profile" 2>/dev/null || true # '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 fi
# D-Bus session is available when autostarted from Cinnamon. # 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") mapfile -t pkgs < <(grep -vE '^\s*(#|$)' "$NIX_PACKAGES_FILE")
if [[ ${#pkgs[@]} -gt 0 ]]; then if [[ ${#pkgs[@]} -gt 0 ]]; then
echo " packages: ${pkgs[*]}" echo " packages: ${pkgs[*]}"
nix profile install --impure "${pkgs[@]}" 2>&1 || { # 'nix profile install' is deprecated as of nix 2.x — use 'nix profile add'
echo "!! nix profile install failed (partial install may have succeeded)"; } nix profile add --impure "${pkgs[@]}" 2>&1 || {
echo "!! nix profile add failed (partial install may have succeeded)"; }
fi fi
fi fi

View File

@@ -121,6 +121,15 @@ NIXSH
echo "live-setup: nix daemon mode configured (trusted-users = $LIVE_USER)" echo "live-setup: nix daemon mode configured (trusted-users = $LIVE_USER)"
fi 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 ─────────────── # ── D-Bus session socket for the live user's login session ───────────────
# dbus-launch is called by lightdm-session / Xsession automatically. # dbus-launch is called by lightdm-session / Xsession automatically.
# Ensure dbus system bus is accessible (needed by nix and Cinnamon). # Ensure dbus system bus is accessible (needed by nix and Cinnamon).