tawasuyu

sergio/takana

> Una distribución Linux construida con un laboratorio funcional y hermético en el > sótano, y una terminal mutable, clásica y anárquica en el piso de arriba — diseñada > desde el suelo para que una IA programadora entienda, modifique y co…

TOML 1572Shell 203Rust 109Markdown 993728 Sutichaykuna

⎇ 82cbdb7e5476ed20d1430f92ab347bcdd85eb8c4 scripts/kde/plasma-start-qemu.sh Shell · 198 siq'ikuna · 10.4 KB Ñawpa willay ch'uya

kde/qemu: KWIN_COMPOSE=Q (QPainter) — esquiva el segfault del rasterizador llvmpipe 82cbdb7e5 · sergio ·

1#!/bin/sh
2# plasma-start-qemu.sh — arranca Plasma en una VM QEMU con render por SOFTWARE (kms_swrast/llvmpipe)
3# sobre el DRM de virtio-gpu (/dev/dri/card0). Derivado de plasma-start-metal.sh pero SIN hardware iris:
4# en QEMU no hay GPU real, así que kwin presenta por el DRM de virtio con EGL/GBM de software.
5#
6# Se instala como /usr/bin/plasma-start en la imagen QEMU y lo AUTO-LANZA /etc/profile (console-getty
7# autologin). Trae los arreglos de la campaña KDE 2026-07: QT_QUICK_BACKEND=software (plasmashell no crea
8# contexto GL sin él), QT_QPA_FONTDIR (mata los tofu; qtbase se construyó sin fontconfig), kdeglobals +
9# QT_QPA_PLATFORMTHEME=kde (iconos + estilo Breeze), kactivitymanagerd (plasmashell aborta sin él).
10#
11# Logs: /tmp/{kwin,kamd,plasmashell}.log + tee a /dev/console.  Salir: matar kwin.
12set -u
13# getty ejecuta este script DIRECTO (no vía login shell) ⇒ PATH viene vacío: mkdir/tr/cat/dbus-daemon
14# no se hallan y kwin nunca levanta. Seteamos PATH explícito (busybox + userland KDE) ANTES de todo.
15export PATH=/usr/bin:/bin:/usr/sbin:/sbin
16# tee a la consola gráfica (tty0) Y al serial (ttyS0) — el host captura ttyS0 con -serial file:
17say() { echo "== plasma-qemu :: $*" | tee -a /dev/console /dev/ttyS0 2>/dev/null; }
18dump() { echo "---- $1 ----" > /dev/ttyS0 2>/dev/null; cat "$1" > /dev/ttyS0 2>/dev/null; }
19
20export LD_LIBRARY_PATH=/usr/lib64:/usr/lib/qt6:/usr/lib:/lib
21export QT_PLUGIN_PATH=/usr/lib64/qt6/plugins:/usr/lib/qt6/plugins
22export QML2_IMPORT_PATH=/usr/lib64/qt6/qml:/usr/lib/qt6/qml
23export QML_IMPORT_PATH=$QML2_IMPORT_PATH
24export XDG_DATA_DIRS=/usr/share
25export XDG_RUNTIME_DIR=/run/user/0
26export XDG_CONFIG_HOME=/root/.config
27export XDG_CACHE_HOME=/root/.cache
28export HOME=/root
29
30# --- render por software sobre virtio-gpu ---
31export LIBGL_ALWAYS_SOFTWARE=1
32export GALLIUM_DRIVER=llvmpipe
33# GBM_ALWAYS_SOFTWARE=1 — EL FIX del segfault (MURO 2, verificado en fuente mesa 24.0.9). virtio-gpu-pci
34# SIN 3D expone un nodo KMS-only (no render-capable). Con MESA_LOADER_DRIVER_OVERRIDE solo, gbm carga
35# kms_swrast pero deja gbm_dri->software=FALSE (dri_screen_create tiene éxito ⇒ nunca cae al fallback
36# dri_screen_create_sw, el único que setea software=true). Entonces dri2_initialize_drm entra al bloque
37# `if(!software)` y llama gbm_dri->mesa->queryCompatibleRenderOnlyDeviceFd() — NULL en el driver software
38# ⇒ SIGSEGV. GBM_ALWAYS_SOFTWARE=1 fuerza dri_screen_create_sw ⇒ software=true ⇒ se salta ese bloque.
39export GBM_ALWAYS_SOFTWARE=1
40# kms_swrast (NO swrast): kwin abre card0 como dispositivo KMS y crea un gbm device sobre él ⇒ necesita
41# el driver de software para KMS (dumb buffers). Con 'swrast' a secas gbm_create_device falla ("Failed
42# to create gbm device"). kms_swrast_dri.so está en /usr/lib/dri.
43export MESA_LOADER_DRIVER_OVERRIDE=kms_swrast
44export LIBGL_DRIVERS_PATH=/usr/lib/dri
45export QT_QUICK_BACKEND=software
46# LP_NUM_THREADS=1: llvmpipe SINCRÓNICO (sin pool de threads del rasterizador) — el JIT multi-thread de
47# llvmpipe segfaultea al componer la 1ra superficie en esta VM. KWIN_DRM_NO_AMS=1: desactiva atomic
48# modesetting (algunos virtio-gpu lo rompen). Ambos son fixes conocidos de kwin/llvmpipe en VMs.
49export LP_NUM_THREADS=1
50# KWIN_DRM_NO_AMS (legacy modeset) fue una corazonada del segfault (que resultó ser GBM_ALWAYS_SOFTWARE).
51# Dejamos atomic (virtio soporta atomic nativo; legacy es el frágil).
52# export KWIN_DRM_NO_AMS=1
53#
54# EL FIX DEL NEGRO: virtio-gpu ADVIERTE soportar drmModeAddFB2WithModifiers pero RECHAZA el modifier
55# explícito (aún LINEAR=0) con EINVAL ⇒ "Failed to create a framebuffer" ⇒ sin output layer ⇒ NEGRO.
56# El modeset inicial usa un buffer dumb (sin modifiers) y SÍ pinta (por eso se ve el wallpaper un instante),
57# pero los buffers del compositor van por AddFB2WithModifiers y fallan ⇒ vuelve a negro. KWIN_DRM_USE_MODIFIERS=0
58# fuerza a kwin a usar drmModeAddFB2 plano (modifier implícito) que virtio-gpu sí acepta.
59export KWIN_DRM_USE_MODIFIERS=0
60# KWIN_COMPOSE=Q — compositor QPainter (raster de Qt directo al buffer, SIN escena llvmpipe). El
61# compositor GL por defecto usa el rasterizador de llvmpipe, cuyo hilo SEGFAULTEA en lp_rast_clear_color
62# → util_fill_rect al limpiar el color buffer (backtrace del core.llvmpipe-0): kwin pinta unos frames y
63# muere → "vuelve a negro". QPainter no arma escenas llvmpipe ⇒ esquiva ese crash. (El segfault viejo con
64# =Q era el de gbm-init, ya resuelto por GBM_ALWAYS_SOFTWARE.) llvmpipe sigue disponible para gbm/EGL.
65export KWIN_COMPOSE=Q
66export QT_QPA_PLATFORM=wayland
67export QT_QPA_PLATFORMTHEME=kde
68export QT_QPA_FONTDIR=/usr/share/fonts/dejavu
69
70# --- DIAGNÓSTICO del segfault-al-1er-composite (MURO 2) ---
71# Sin gdb en la imagen: subimos el logging categorizado de kwin (kwin_core/drm/scene/opengl) + mesa/egl
72# para ver EN QUÉ FASE muere (bind EGL, alloc GBM, JIT llvmpipe, o el paint real). DIAG=0 para apagarlo.
73if [ "${DIAG:-1}" = 1 ]; then
74  export QT_LOGGING_RULES="kwin_*=true;qt.qpa.*=true"
75  export EGL_LOG_LEVEL=debug
76  export LIBGL_DEBUG=verbose
77  export MESA_DEBUG=1
78  export GALLIUM_HUD=          # no HUD, sólo para dejar constancia
79  export KWIN_DRM_DEBUG=1
80fi
81
82mkdir -p "$XDG_RUNTIME_DIR" "$XDG_CONFIG_HOME" "$XDG_CACHE_HOME" /run/dbus /root
83chmod 700 "$XDG_RUNTIME_DIR"
84[ -s /etc/machine-id ] || cat /proc/sys/kernel/random/uuid 2>/dev/null | tr -d - > /etc/machine-id
85
86# kdeglobals: iconos + estilo Breeze (sin esto Qt cae a hicolor vacío = escritorio pelado)
87cat > "$XDG_CONFIG_HOME/kdeglobals" <<EOF
88[Icons]
89Theme=breeze
90
91[General]
92ColorScheme=BreezeLight
93widgetStyle=Breeze
94
95[KDE]
96widgetStyle=Breeze
97EOF
98
99say "GPU DRM: $(ls /dev/dri/ 2>/dev/null | tr '\n' ' ')"
100[ -e /dev/dri/card0 ] || say "!! no hay /dev/dri/card0 — ¿virtio-gpu no cargó? (dmesg | grep -i drm)"
101
102# D-Bus de SISTEMA: sin él, kf.solid/udisks2 spamea "Not connected to D-Bus server" y powerdevil + los
103# applets de dispositivos/energía no inician. Escucha en el path estándar /run/dbus/system_bus_socket
104# (los clientes lo hallan por DBUS_SYSTEM_BUS_ADDRESS por defecto ⇒ no exportamos nada). Corre como root
105# y hace setuid a messagebus (uid 81, sembrado en el passwd de la imagen). No hay udisksd/upowerd reales
106# en el rootfs ⇒ no habrá discos/batería, pero el bus existe y solid deja de errorear en cada poll.
107mkdir -p /run/dbus /var/lib/dbus
108cp -f /etc/machine-id /var/lib/dbus/machine-id 2>/dev/null || true
109if [ ! -S /run/dbus/system_bus_socket ]; then
110  if dbus-daemon --system --fork 2>/tmp/dbus-system.log; then
111    say "system bus ON (/run/dbus/system_bus_socket)"
112  else
113    say "!! system bus NO arrancó:"; dump /tmp/dbus-system.log
114  fi
115fi
116
117# D-Bus de sesión
118if [ -z "${DBUS_SESSION_BUS_ADDRESS:-}" ]; then
119  DBUS_SESSION_BUS_ADDRESS=$(dbus-daemon --session --fork --print-address 2>/dev/null)
120  export DBUS_SESSION_BUS_ADDRESS
121fi
122say "dbus: ${DBUS_SESSION_BUS_ADDRESS:-NO ARRANCO}"
123
124# --- CORE DUMP del segfault (MURO 2): sin gdb en la imagen, sacamos un core y lo leemos con el gdb del
125# host apuntando al rootfs fundido. Localiza el frame culpable (libLLVM/llvmpipe vs kwin vs mesa). ---
126if [ "${DIAG:-1}" = 1 ]; then
127  ulimit -c unlimited 2>/dev/null || true
128  # /core en la RAÍZ ext4 (NO /tmp: es tmpfs=RAM y se pierde al matar QEMU). Tras el crash hacemos sync
129  # explícito ⇒ el core persiste en la imagen aunque después mate QEMU con SIGKILL.
130  echo '/core.%e.%p' > /proc/sys/kernel/core_pattern 2>/dev/null || true
131  say "core dumps ON (pattern=$(cat /proc/sys/kernel/core_pattern 2>/dev/null), ulimit -c=$(ulimit -c))"
132fi
133
134# SÓLO el card de virtio-gpu: el efifb/simpledrm sobrevive como 2º DRM ("Unknown-1", read-only) y kwin
135# intenta manejar ambos outputs ⇒ conflicto de presentación ⇒ pinta y vuelve a NEGRO. Detectamos el card
136# cuyo driver es virtio_gpu (robusto al numerado card0/card1 que cambia entre boots) y se lo pasamos a kwin.
137VIRTIO_CARD=
138for c in /dev/dri/card*; do
139  n=$(basename "$c")
140  drv=$(readlink -f "/sys/class/drm/$n/device/driver" 2>/dev/null)
141  case "$drv" in *virtio*) VIRTIO_CARD="$c"; break;; esac
142done
143if [ -n "$VIRTIO_CARD" ]; then
144  export KWIN_DRM_DEVICES="$VIRTIO_CARD"
145  say "KWIN_DRM_DEVICES=$VIRTIO_CARD (ignorando efifb/simpledrm)"
146else
147  say "!! no hallé card virtio_gpu; kwin verá todos los DRM (posible doble output)"
148fi
149
150# Compositor sobre el DRM de virtio (software EGL/GBM vía kms_swrast). SIN --virtual: presenta al display.
151say "lanzando kwin_wayland (DRM virtio, software GL)..."
152/usr/bin/kwin_wayland --drm >/tmp/kwin.log 2>&1 &
153KWIN=$!
154# stream EN VIVO del kwin.log al serial (busybox sed NO soporta -u ⇒ nada de sed/pipes: tail -f directo).
155( echo "==== kwin.log (stream vivo) ===="; tail -f /tmp/kwin.log ) > /dev/ttyS0 2>/dev/null &
156TAILPID=$!
157i=0
158while [ $i -lt 60 ]; do
159  [ -S "$XDG_RUNTIME_DIR/wayland-0" ] && break
160  kill -0 $KWIN 2>/dev/null || { say "!! kwin murio:"; dump /tmp/kwin.log; exec /bin/sh; }
161  i=$((i+1)); sleep 0.5
162done
163if [ -S "$XDG_RUNTIME_DIR/wayland-0" ]; then
164  say "compositor OK (wayland-0)"
165else
166  say "!! kwin no expuso wayland-0:"; dump /tmp/kwin.log; exec /bin/sh
167fi
168export WAYLAND_DISPLAY=wayland-0
169
170# kactivitymanagerd: plasmashell ABORTA sin el
171KAMD=$(ls /usr/lib*/libexec/kactivitymanagerd 2>/dev/null | head -1)
172[ -n "$KAMD" ] && { "$KAMD" >/tmp/kamd.log 2>&1 & sleep 2; say "kactivitymanagerd lanzado"; }
173
174say "lanzando plasmashell..."
175/usr/bin/plasmashell >/tmp/plasmashell.log 2>&1 &
176sleep 8
177say "procesos: $(ps axo comm 2>/dev/null | grep -E 'kwin|plasma' | sort -u | tr '\n' ' ')"
178say "escritorio arriba (o mira /tmp/plasmashell.log). Ctrl-C mata la sesion."
179dump /tmp/plasmashell.log
180# monitor de estado: cada 15s dice si kwin/plasmashell siguen vivos ⇒ si vuelve a negro, sabremos si
181# fue plasmashell que murió (containment) o kwin/output. (busybox pgrep -c cuenta procesos.)
182( n=0; while sleep 15; do
183    n=$((n+1))
184    say "STATUS +$((n*15))s: kwin=$(pgrep kwin_wayland 2>/dev/null | wc -l) plasmashell=$(pgrep plasmashell 2>/dev/null | wc -l)"
185  done ) &
186wait $KWIN
187RC=$?
188# kwin salió ⇒ volcá su log para saber por qué (backend QPainter, DRM, modeset…)
189say "kwin salió (código $RC) — volcando kwin.log:"
190dump /tmp/kwin.log
191# copiar los logs a la ext4 raíz y SYNC ⇒ core + logs persisten en la imagen para leer desde el host
192# con debugfs/gdb (el SIGKILL de QEMU no sincroniza; sin este sync se pierde todo lo de esta sesión).
193cp /tmp/kwin.log /kwin.log 2>/dev/null || true
194cp /tmp/plasmashell.log /plasmashell.log 2>/dev/null || true
195say "cores en /: $(ls -la /core.* 2>/dev/null | tr '\n' ' ' || echo NINGUNO)"
196sync; sync
197say "== disco SYNCED (core+logs en la raíz). serial CONGELADO. matá QEMU desde el host. =="
198sleep 3600