From 21de42b6b1eb9e097f3e51bee3e3a5bb46656140 Mon Sep 17 00:00:00 2001 From: mozempk Date: Sat, 25 Apr 2026 21:38:07 +0200 Subject: [PATCH] feat(niri-live): dual-kernel boot menu, audio fix, elogind fix, rsync optimization - Add kernel 7 (linux-mainline) as primary boot entry - Add kernel 6 (linux) as secondary fallback boot entry - Simplified boot menu: single entry per kernel, no failsafe variants - Add snd-intel-dspcfg.dsp_driver=1 + snd_hda_intel.dmic_detect=0 to BOOT_CMDLINE - Fix elogind sv: dual D-Bus + PID check to suppress already-running warnings - Replace cp -rfpPv with rsync -aHX in copy_include_directories (nixpkgs speed fix) - Fix trailing slash bash glob bug in mklive.sh and postsetup-nvidia.sh - Add -v linux-mainline to _inner-build-niri-live.sh for correct primary kernel --- .../mainline-niri/packages.live-desktop.list | 3 + iso/_inner-build-niri-live.sh | 5 + iso/build-niri-live-iso.sh | 41 ++++- .../0003-dual-kernel-simplified-menu.patch | 161 ++++++++++++++++++ iso/postsetup-nvidia.sh | 3 +- 5 files changed, 205 insertions(+), 8 deletions(-) create mode 100644 iso/patches/0003-dual-kernel-simplified-menu.patch diff --git a/config/profiles/mainline-niri/packages.live-desktop.list b/config/profiles/mainline-niri/packages.live-desktop.list index 8874f10..70b3fef 100644 --- a/config/profiles/mainline-niri/packages.live-desktop.list +++ b/config/profiles/mainline-niri/packages.live-desktop.list @@ -6,6 +6,9 @@ base-system linux-mainline linux-mainline-headers +# Kernel 6 (stable) included for dual-boot menu entry fallback. +linux +linux-headers linux-firmware linux-firmware-network intel-ucode diff --git a/iso/_inner-build-niri-live.sh b/iso/_inner-build-niri-live.sh index e0eb980..52df4d3 100755 --- a/iso/_inner-build-niri-live.sh +++ b/iso/_inner-build-niri-live.sh @@ -208,6 +208,10 @@ trap _cleanup_mklive_builds EXIT # mklive prepends -r args: LAST -r = HIGHEST priority. # Our local signed repo is last so xbps resolves noctalia-* from it. +# -v linux-mainline: makes mainline (kernel 7) the PRIMARY boot kernel; +# mklive.sh sets KERNELVERSION from it and ignores the linux metapackage. +# The plain 'linux' (kernel 6) in ISO_PKGS still gets installed and the +# secondary-kernel loop in mklive.sh builds its initramfs + boot entry. ./mklive.sh \ -a "$ARCH" \ -r "$REPO_URL" \ @@ -219,6 +223,7 @@ trap _cleanup_mklive_builds EXIT -k "$KEYMAP" \ -l "$LOCALE" \ -T "$ISO_TITLE" \ + -v linux-mainline \ -p "$ISO_PKGS" \ -I "$INCLUDE_DIR" \ -x "$PROJECT_DIR/iso/postsetup-nvidia.sh" \ diff --git a/iso/build-niri-live-iso.sh b/iso/build-niri-live-iso.sh index e4bd2cf..9840909 100755 --- a/iso/build-niri-live-iso.sh +++ b/iso/build-niri-live-iso.sh @@ -205,25 +205,52 @@ install -d -m 0755 "$INCLUDE_DIR/etc/sv/elogind" cat > "$INCLUDE_DIR/etc/sv/elogind/run" <<'EOF' #!/bin/sh exec 2>&1 -# If elogind is already running (e.g. from a previous attempt), stay up -# permanently rather than letting runit restart the wrapper every 3 s. -if [ -f /run/elogind.pid ] && kill -0 "$(cat /run/elogind.pid 2>/dev/null)" 2>/dev/null; then - echo "elogind-sv: already running (PID $(cat /run/elogind.pid)), yielding" + +# Helper: is elogind's login1 D-Bus name already registered on the system bus? +_login1_on_dbus() { + dbus-send --system --print-reply --dest=org.freedesktop.DBus \ + /org/freedesktop/DBus org.freedesktop.DBus.GetNameOwner \ + string:org.freedesktop.login1 >/dev/null 2>&1 +} + +# Helper: is elogind process alive via its PID file? +_elogind_alive() { + for _pf in /run/elogind.pid /run/elogind/elogind.pid; do + [ -f "$_pf" ] && kill -0 "$(cat "$_pf" 2>/dev/null)" 2>/dev/null && return 0 + done + return 1 +} + +# If elogind is already running (process alive or D-Bus name taken), yield +# permanently so runit does not spam restarts. +if _elogind_alive || _login1_on_dbus; then + echo "elogind-sv: already running — yielding to avoid restart spam" exec tail -f /dev/null fi + # Wait for dbus socket — poll every second, up to 30s i=0 while [ $i -lt 30 ] && [ ! -S /run/dbus/system_bus_socket ]; do sleep 1; i=$((i+1)) done + exec /usr/libexec/elogind/elogind.wrapper EOF chmod 0755 "$INCLUDE_DIR/etc/sv/elogind/run" -# finish: rate-limit restarts to avoid "already running" spam +# finish: rate-limit restarts; if the run was very short (elogind crashed or +# reported "already running" before our detection), back off longer. cat > "$INCLUDE_DIR/etc/sv/elogind/finish" <<'EOF' #!/bin/sh -sleep 3 +# $1=exitcode, $2=signal (or -1) +exitcode="$1" +# Non-zero exit with no signal = elogind bailed out (e.g. "already running"). +# Sleep longer to avoid log spam; next run will yield via the D-Bus/PID check. +if [ "$exitcode" != "0" ] && [ "$2" = "-1" ]; then + sleep 10 +else + sleep 3 +fi EOF chmod 0755 "$INCLUDE_DIR/etc/sv/elogind/finish" @@ -832,7 +859,7 @@ ISO_PKGS=$(grep -vE '^\s*(#|$)' \ | tr '\n' ' ') TS="$(date -u +%Y%m%d)" OUT_ISO="${OUTPUT_ISO:-$OUT_DIR/void-live-niri-${TS}.iso}" -BOOT_CMDLINE="${BOOT_CMDLINE:-live.user=${LIVE_USER} console=tty0 console=ttyS0,115200 nvidia-drm.modeset=1 rd.driver.blacklist=nouveau modprobe.blacklist=nouveau btusb.enable_autosuspend=0}" +BOOT_CMDLINE="${BOOT_CMDLINE:-live.user=${LIVE_USER} console=tty0 console=ttyS0,115200 nvidia-drm.modeset=1 rd.driver.blacklist=nouveau modprobe.blacklist=nouveau btusb.enable_autosuspend=0 snd-intel-dspcfg.dsp_driver=1 snd_hda_intel.dmic_detect=0}" echo ">>> running mklive.sh inside docker — output: $OUT_ISO" "$DOCKER" run --rm --privileged \ diff --git a/iso/patches/0003-dual-kernel-simplified-menu.patch b/iso/patches/0003-dual-kernel-simplified-menu.patch new file mode 100644 index 0000000..a6eac23 --- /dev/null +++ b/iso/patches/0003-dual-kernel-simplified-menu.patch @@ -0,0 +1,161 @@ +--- a/mklive.sh 2026-04-25 21:08:53.137743383 +0200 ++++ b/mklive.sh 2026-04-25 21:25:02.321939679 +0200 +@@ -211,7 +211,7 @@ + copy_include_directories() { + for includedir in "${INCLUDE_DIRS[@]}"; do + info_msg "=> copying include directory '$includedir' ..." +- find "$includedir" -mindepth 1 -maxdepth 1 -exec cp -rfpPv {} "$ROOTFS"/ \; ++ rsync -aHX "$includedir"/ "$ROOTFS"/ + done + } + +@@ -229,6 +229,41 @@ + i686*|x86_64*) cp "$ROOTFS/boot/vmlinuz-$KERNELVERSION" "$BOOT_DIR"/vmlinuz ;; + aarch64*) cp "$ROOTFS/boot/vmlinux-$KERNELVERSION" "$BOOT_DIR"/vmlinux ;; + esac ++ ++ # Generate boot files for secondary kernels installed alongside KERNELVERSION. ++ SECONDARY_BOOT_KERNELS=() ++ for _kdir in "$ROOTFS/usr/lib/modules"/*/; do ++ [[ -d "${_kdir}/kernel" ]] || continue ++ # Strip trailing slash before extracting basename (glob */ appends /) ++ _kver="${_kdir%/}"; _kver="${_kver##*/}" ++ [[ "$_kver" == "$KERNELVERSION" ]] && continue ++ info_msg "Secondary kernel ${_kver}: generating live initramfs..." ++ chroot "$ROOTFS" env -i /usr/bin/dracut -N --"${INITRAMFS_COMPRESSION}" \ ++ --add-drivers "ahci" --force-add "vmklive autoinstaller" --omit systemd \ ++ "/boot/initrd-${_kver}" "${_kver}" || { ++ echo "WARNING: dracut failed for secondary kernel ${_kver} — skipping" ++ continue ++ } ++ mv "$ROOTFS/boot/initrd-${_kver}" "$BOOT_DIR/initrd-${_kver}" ++ case "$TARGET_ARCH" in ++ i686*|x86_64*) ++ if [[ -f "$ROOTFS/boot/vmlinuz-${_kver}" ]]; then ++ cp "$ROOTFS/boot/vmlinuz-${_kver}" "$BOOT_DIR/vmlinuz-${_kver}" ++ else ++ echo "WARNING: vmlinuz-${_kver} not found — skipping secondary kernel" ++ rm -f "$BOOT_DIR/initrd-${_kver}"; continue ++ fi ;; ++ aarch64*) ++ if [[ -f "$ROOTFS/boot/vmlinux-${_kver}" ]]; then ++ cp "$ROOTFS/boot/vmlinux-${_kver}" "$BOOT_DIR/vmlinux-${_kver}" ++ else ++ echo "WARNING: vmlinux-${_kver} not found — skipping secondary kernel" ++ rm -f "$BOOT_DIR/initrd-${_kver}"; continue ++ fi ;; ++ esac ++ SECONDARY_BOOT_KERNELS+=("${_kver}") ++ info_msg "Secondary kernel ${_kver}: boot files staged" ++ done + } + + array_contains() { +@@ -273,6 +308,17 @@ + -e "s|@@BOOT_CMDLINE@@|${BOOT_CMDLINE}|" \ + "$ISOLINUX_DIR"/isolinux.cfg + ++ # Append entries for secondary kernels (standard boot only). ++ for _skver in "${SECONDARY_BOOT_KERNELS[@]+"${SECONDARY_BOOT_KERNELS[@]}"}"; do ++ cat >> "$ISOLINUX_DIR"/isolinux.cfg << SEOF ++ ++LABEL linux-${_skver%%_*} ++MENU LABEL ${BOOT_TITLE} ${_skver} ${TARGET_ARCH} ++KERNEL /boot/vmlinuz-${_skver} ++APPEND initrd=/boot/initrd-${_skver} root=live:CDLABEL=VOID_LIVE init=/sbin/init ro rd.luks=0 rd.md=0 rd.dm=0 loglevel=4 vconsole.unicode=1 vconsole.keymap=${KEYMAP} locale.LANG=${LOCALE} ${BOOT_CMDLINE} ++SEOF ++ done ++ + # include memtest86+ + if [ -e "$VOIDTARGETDIR"/boot/memtest86+/memtest.bin ]; then + cp "$VOIDTARGETDIR"/boot/memtest86+/memtest.bin "$BOOT_DIR" +@@ -290,15 +336,16 @@ + esac + + write_entry() { +- local entrytitle="$1" id="$2" cmdline="$3" dtb="$4" hotkey="$5" ++ local entrytitle="$1" id="$2" cmdline="$3" dtb="$4" hotkey="$5" \ ++ kimg="${6:-${KERNEL_IMG}}" kidrd="${7:-initrd}" + cat << EOF >> "$GRUB_DIR"/grub_void.cfg + menuentry "${entrytitle}" --id "${id}" ${hotkey:+--hotkey $hotkey} { + set gfxpayload="keep" +- linux (\${voidlive})/boot/${KERNEL_IMG} \\ ++ linux (\${voidlive})/boot/${kimg} \\ + root=live:CDLABEL=VOID_LIVE ro init=/sbin/init \\ + rd.luks=0 rd.md=0 rd.dm=0 loglevel=4 gpt add_efi_memmap \\ + vconsole.unicode=1 vconsole.keymap=${KEYMAP} locale.LANG=${LOCALE} ${cmdline} +- initrd (\${voidlive})/boot/initrd ++ initrd (\${voidlive})/boot/${kidrd} + EOF + if [ -n "${dtb}" ]; then + printf ' devicetree (${voidlive})/boot/dtbs/%s\n' "${dtb}" >> "$GRUB_DIR"/grub_void.cfg +@@ -311,23 +358,25 @@ + + ENTRY_TITLE="${BOOT_TITLE} ${KERNELVERSION} ${title_sfx}(${TARGET_ARCH})" + ++ # Standard boot only — failsafe/RAM/speech variants removed. + write_entry "${ENTRY_TITLE}" "linux${id_sfx}" \ + "$BOOT_CMDLINE $cmdline" "$dtb" +- write_entry "${ENTRY_TITLE} (RAM)" "linuxram${id_sfx}" \ +- "rd.live.ram $BOOT_CMDLINE $cmdline" "$dtb" +- write_entry "${ENTRY_TITLE} (graphics disabled)" "linuxnogfx${id_sfx}" \ +- "nomodeset $BOOT_CMDLINE $cmdline" "$dtb" +- write_entry "${ENTRY_TITLE} with speech" "linuxa11y${id_sfx}" \ +- "live.accessibility live.autologin $BOOT_CMDLINE $cmdline" "$dtb" 's' +- write_entry "${ENTRY_TITLE} with speech (RAM)" "linuxa11yram${id_sfx}" \ +- "live.accessibility live.autologin rd.live.ram $BOOT_CMDLINE $cmdline" "$dtb" 'r' +- write_entry "${ENTRY_TITLE} with speech (graphics disabled)" "linuxa11ynogfx${id_sfx}" \ +- "live.accessibility live.autologin nomodeset $BOOT_CMDLINE $cmdline" "$dtb" 'g' + + } + + write_entries + ++ # Secondary kernel entries (standard boot only). ++ for _skver in "${SECONDARY_BOOT_KERNELS[@]+"${SECONDARY_BOOT_KERNELS[@]}"}"; ++ do ++ case "$TARGET_ARCH" in ++ i686*|x86_64*) _skimg="vmlinuz-${_skver}" ;; ++ aarch64*) _skimg="vmlinux-${_skver}" ;; ++ esac ++ write_entry "${BOOT_TITLE} ${_skver} (${TARGET_ARCH})" \ ++ "linux-${_skver%%_*}" "$BOOT_CMDLINE" "" "" "${_skimg}" "initrd-${_skver}" ++ done ++ + for platform in "${PLATFORMS[@]}"; do + ( + . "platforms/${platform}.sh" +--- a/isolinux/isolinux.cfg.in 2026-04-25 21:08:53.137743383 +0200 ++++ b/isolinux/isolinux.cfg.in 2026-04-25 21:13:05.897818309 +0200 +@@ -25,31 +25,6 @@ + KERNEL /boot/vmlinuz + APPEND initrd=/boot/initrd root=live:CDLABEL=VOID_LIVE init=/sbin/init ro rd.luks=0 rd.md=0 rd.dm=0 loglevel=4 vconsole.unicode=1 vconsole.keymap=@@KEYMAP@@ locale.LANG=@@LOCALE@@ @@BOOT_CMDLINE@@ + +-LABEL linuxram +-MENU LABEL @@BOOT_TITLE@@ @@KERNVER@@ @@ARCH@@ (RAM) +-KERNEL /boot/vmlinuz +-APPEND initrd=/boot/initrd root=live:CDLABEL=VOID_LIVE init=/sbin/init ro rd.luks=0 rd.md=0 rd.dm=0 loglevel=4 vconsole.unicode=1 vconsole.keymap=@@KEYMAP@@ locale.LANG=@@LOCALE@@ @@BOOT_CMDLINE@@ rd.live.ram +- +-LABEL linuxnogfx +-MENU LABEL @@BOOT_TITLE@@ @@KERNVER@@ @@ARCH@@ (graphics disabled) +-KERNEL /boot/vmlinuz +-APPEND initrd=/boot/initrd root=live:CDLABEL=VOID_LIVE init=/sbin/init ro rd.luks=0 rd.md=0 rd.dm=0 loglevel=4 vconsole.unicode=1 vconsole.keymap=@@KEYMAP@@ locale.LANG=@@LOCALE@@ @@BOOT_CMDLINE@@ nomodeset +- +-LABEL linuxa11y +-MENU LABEL @@BOOT_TITLE@@ @@KERNVER@@ @@ARCH@@ with ^speech +-KERNEL /boot/vmlinuz +-APPEND initrd=/boot/initrd root=live:CDLABEL=VOID_LIVE init=/sbin/init ro rd.luks=0 rd.md=0 rd.dm=0 loglevel=4 vconsole.unicode=1 vconsole.keymap=@@KEYMAP@@ locale.LANG=@@LOCALE@@ @@BOOT_CMDLINE@@ live.accessibility live.autologin +- +-LABEL linuxa11yram +-MENU LABEL @@BOOT_TITLE@@ @@KERNVER@@ @@ARCH@@ with speech (^RAM) +-KERNEL /boot/vmlinuz +-APPEND initrd=/boot/initrd root=live:CDLABEL=VOID_LIVE init=/sbin/init ro rd.luks=0 rd.md=0 rd.dm=0 loglevel=4 vconsole.unicode=1 vconsole.keymap=@@KEYMAP@@ locale.LANG=@@LOCALE@@ @@BOOT_CMDLINE@@ live.accessibility live.autologin rd.live.ram +- +-LABEL linuxa11ynogfx +-MENU LABEL @@BOOT_TITLE@@ @@KERNVER@@ @@ARCH@@ with speech (^graphics disabled) +-KERNEL /boot/vmlinuz +-APPEND initrd=/boot/initrd root=live:CDLABEL=VOID_LIVE init=/sbin/init ro rd.luks=0 rd.md=0 rd.dm=0 loglevel=4 vconsole.unicode=1 vconsole.keymap=@@KEYMAP@@ locale.LANG=@@LOCALE@@ @@BOOT_CMDLINE@@ live.accessibility live.autologin nomodeset +- + LABEL c + MENU LABEL Boot first HD found by BIOS + COM32 chain.c32 diff --git a/iso/postsetup-nvidia.sh b/iso/postsetup-nvidia.sh index 65d2010..2ee69b1 100755 --- a/iso/postsetup-nvidia.sh +++ b/iso/postsetup-nvidia.sh @@ -53,7 +53,8 @@ sed 's/^/ /' "$ROOTFS/etc/dracut.conf.d/10-nvidia.conf" found=0 for kdir in "$ROOTFS/usr/lib/modules"/*/; do [[ -d "${kdir}/kernel" ]] || continue - kver="${kdir##*/}" + # Strip trailing slash before extracting basename (glob */ appends /) + kver="${kdir%/}"; kver="${kver##*/}" found=1 # Verify nvidia.ko is present for this kernel version.