From 7f2fdd5a41c5a5ce2a2bbab3c3d547b6f71419b9 Mon Sep 17 00:00:00 2001 From: sergio Date: Wed, 29 Jul 2026 22:36:43 -0400 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=8A=20audio=20FUNCIONANDO=20=E2=80=94?= =?UTF-8?q?=20el=20muro=20era=20libudev-zero,=20y=20ensancharlo=20de=20m?= =?UTF-8?q?=C3=A1s=20romp=C3=ADa=20el=20v=C3=ADdeo?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Audio ├─ Devices: 48. HDA Intel [alsa] ├─ Sinks: * 52. HDA Intel Analog Stereo [vol: 0.40] ├─ Sources: * 53. HDA Intel Analog Stereo [vol: 1.00] Y gvc con perfiles reales (`output:analog-stereo+input:analog-stereo`). Se fue el auto_null. LA CAUSA: SPA pide el device `card` (alsa-udev.c:178-183), que no tiene major:minor, y libudev-zero recorría SÓLO /sys/dev/{block,char} — sólo devices CON nodo. El device que SPA necesita nunca entraba en la enumeración: no faltaba una propiedad, faltaba la mitad del espacio de búsqueda. **Y LA PRIMERA VERSIÓN DEL PARCHE ARREGLÓ EL AUDIO Y ROMPIÓ EL VÍDEO.** Recorría /sys/class entero, y /sys/class/drm no trae sólo tarjetas: trae los CONECTORES (card0-Virtual-1) y un fichero `version`, ninguno con nodo. Mutter los tomaba como candidatos ⇒ `No available CRTC for monitor` + `Page flip failed: drmModeAtomicCommit: Invalid argument` en bucle. Pantalla negra con el compositor vivo: el mismo síntoma de antes por una causa nueva. El udev real también los enumera, pero les adjunta las propiedades por las que mutter los descarta, y ésas libudev-zero no las sintetiza. La lección, que vale para cualquier reimplementación parcial de una API: **ensanchar la enumeración expone los huecos de PROPIEDADES a más consumidores. Los dos lados del contrato tienen que crecer juntos.** El parche final lleva una LISTA ACOTADA de subsistemas (`sound` hoy); agregar otro es una línea *y* una prueba de que el consumidor lo necesita y no se rompe. POR QUÉ NO eudev — y corrijo mi propia sugerencia de antes, que era la peor opción: el repo ya lo había probado en otro frente y ROMPIÓ EL INPUT. Su libudev.so.1 pisa el de libudev-zero y, sin udevd, no expone ID_INPUT ⇒ libinput ignora todos los dispositivos en silencio. Verificación A/B en QEMU de aquel episodio: eudev = 0 «New device», libudev-zero = 5. eudev sin udevd es PEOR, y correr udevd contradice la arquitectura (arje-zero es PID1). El arreglo va donde está el hueco. Radio pagado: 51 sellados a deuda, 9 en el cierre GNOME (reconstruidos: libinput, libgudev, colord, mutter, gnome-shell, libgdm, upower, pipewire, wireplumber). El resto —base, cli, KDE— queda para el latido. Captura actualizada: escritorio pintando (628 colores) Y audio, cero page-flip fallidos. Co-Authored-By: Claude Opus 5 (1M context) --- .../evidencia/gnome-shell-qemu-2026-07-29.png | Bin 22582 -> 22265 bytes docs/runbooks/gnome-qemu-desktop.md | 47 +++++++++ recipes/libudev-zero-scan-class.patch | 96 ++++++++++++++++++ recipes/libudev-zero.toml | 9 ++ 4 files changed, 152 insertions(+) create mode 100644 recipes/libudev-zero-scan-class.patch diff --git a/docs/evidencia/gnome-shell-qemu-2026-07-29.png b/docs/evidencia/gnome-shell-qemu-2026-07-29.png index 3284246002f47a90845c806b5b94d038c037096f..f95b0ff4e78608db426d525123b92cb820756ab5 100644 GIT binary patch literal 22265 zcmeFZc{tSV`#=0fp%6C}WlMWXM6#Q1DwVB5Dr?!27>s=|l(pZUlNElgQSW3R$nC0Ym;N^Nid!7=jvKVOzqw*(OFV*|IC|pf zMgFrTk*5!_CLa>}Li&0+`Cey#_dSQMZlBJ=!me(McRm)$-G~3Z{a5n-iM@v3IFIfK z8kE?jv+KmsH#XZFws4N!!U?|G@6V)-DA4x* z?(fg@S~-_2#vE;d$ybPzQ^Nj+Eq_dmil-9>gGtkZb5;c@9u0_4nwq&4X7xOW1L2hL zrOh+&kGei75PS{NI9QRFsZTkoA3c8j4`u~Z2(P+2_C#Lp8{Xu<}Eze+g_yTI?T?`59Hh*kMLjrB<(kQT9d;-b!#Din7&bz;Jez; z)z#(Dol&w<$Jk!-tTfrYz-2n==|BB0%FJVSrCz*eczC!YA3an`Vo(wp?(>-_#qv=z z&mmy~Z3!jp@s1a_`AK2u^9IWoUk)}e>iU6N)1(SNs)PC3*Ef2~xp+KXW(m!p)6$Kz z@suf(@a5Y2AJOW5RJ>oTw%TqaC2LxZ=-v2UYM>zfQ$D73o3i#^%B1vhU%P$BJ$3qu zeh}YT{N}&C`}f7ikDnx;6l zD%vi=#fv1Y@g+MOwfL=rzA8=V8CLh3DCz2w*N!?{G4}j)R`J+#o5uG>#ywNzkt-Fw zGMSl>u)Z4UZBr;2PnQ1r_3H)4{`DF`bC1zy(#1slmL?|}J79vLe>ZM2S}GoI z>A`Q1ThzA(8>K79O6P}tEvux(F09J6D1Q1dYNNXTTQfD@W9oMz+Hd~-1CN8q+p?!D zrpCq!bIBHKF~;)p@}iWA3l}cnsa@G3C4LRBYvG1qM!`#szBwLsM(Ox;S3UW`_r3Yz z$Uk?DjeFopRBlg74|G%PT5U2+Hw9_uS`3|2&l%xB6QXwbj?^ zPi;oid*pje$DblB|NN*v_Pe0qlm4p&xAxF+_xcm@ZtXwAUIa)55_6T zr=*)g$j;Brv2$=#Zq`cM6+VWDUMeH*l2{n7z;=%EKwR|JUmtq2sJ`a?k9-pR>-luMd2qlI#%k*UX{`R+{NxmGvj3ft!XxE@i$3!aXi9^xPL$`mBm3XRHFsQ>Zpt&W=YV(!M3~dC9LhB@CTLsHDd9l>78##rK$z z-!~ncg&D+of3e?PQ=!adypBWM_fXIcBO`gcmW6-CB%5a_91m86&n1w2< z*de%RU4FN@Ig#M?0FI-St&SHIKE5_AiAWBFi>hdFatWTz`1P>yxfkzTvpOEGq8@a^*x1;}sKB2V>^|Qe!gsc0V(k6<_tvtM zF~Q1{LBD%?$W?5pM(?Me%qJJ}TT3V3$Lgt(yd%`9y{FAr=0e1jt?^`dgW6>0vSUwr^jXv56&~ZS0 zvpS+2=8@{`=Qjrr9^5ld_wn%&!#T+8YwCQc6RFj_PQv&4 z+*;MhbULwe5(a<1;Y8wKZ}0l%csgSoMPE}PQ1k)^&iKAdBC{JCNBGbDx*0-7Gd7|L z)Xc^xDHCPv#zJ^_OMycV6iUKoB7@>`EK9K@QVW9Bgt-3E6L5A}^Z z;R+|%Zs6zU=k-yvZ^BNShJJp2c6QS{1x+WsLJ+>xxdrL&EHfgSI81bjj&Wc#Vu zO7})7!da3t67X8ddY2ogMC8>txAtp)oehFq)B5Y(X$}q!Z8bi?1II79_V&!W`H<$i zAilI^V{XkZ4AM5oBj996!0rpG0h*j_Y;32Evj+2Q8Yd!bSCc#L!ztlEM1+J+lJ3AU zK3x1BbQ-ISJ=7Pv?(K^kBc_wJp}S2Q)hzdX=kVlpuI=k@ig ztIolw7lw~=ikL4?@={B@iYIA({jJX>IHu0)HZ~#nEqU>P{xrayi!1+)$j*`wM1xZz zUN6dr6VZ8l>F~`t2_)!HK;Y{}J%Xm(9e%dAX-`XHuMwIoh_XT_l~}mn>fBzk)!XCv z3Xj-Gt@U_~Rn6*9j$6yzaAg%b8TK?cR!{t3mF9r9{COn&XJC!4o&L^{j6O>q?zhho z_Uj`TX(=7EgDj>-MqSRz_av8|v$e zyq@f8?)p%&moRtn+NOx5Wu8r~lLumVAvid=)O&4z(}#0%(HWAYt1OBlPoJiVs(7fb zHBHgB$acyKkynFWT|Js$!lkxe*&Z(N&ntxec-K#=sB*l{@%?8_-8yfsl^ic8At0oTIqp1Gt-$5erz!P$K_)v0%k45MN6t3ZNij;L(x{S@x+i-Bei@pW6!}s@q0EF_SpMB6{#i!G zdxwlnbbBAJeb!Aj+O*Uyn!5AL;t#HNAk62-?ZD zU;e^93il04Ol<6Qiy5CQ&BT&l=)-wdp$|GC+ufB(N&ZWN-pOM8$Qx_8A2^w9Kp;PV zRn^f0%5x3Bv$x?(BO{5(%9pR#TM{czawqQSuBw_?!K+x-h*HOsP4JV znN(1a`RxT>!T%XNcT$GXs3J+H+^H>y%3S@Ei;tv(cKc%Fw zCoNrNlZ;aqEngG-paX-`{v}I2&Z3H^3(c8SQDH+}?{*R0iwG<&)9D;Sg3RFmuGnv9 zX67#0Rb*8ko+Ncp=;MN7zuXNCe>RS{A*H2rRB8-gO%AXABQ)CH(b25TLo;yxIDhC) zuBp~UoS~+srfl>Akw{z`hVQqK<`u+7zl5Xcy;k9O_i7Z6hnGQ`iCFH23~>W4M^?tL zQX&ZA-CCbj+z&bfLFs$tUN-~N#c|uYjZxw#$Nq0HfPC%l?(Q9_MdI$AaiOB?KNN}O zn5h=EM;Se(GyihkyLa#S162gE`N1tC(`D0xF8mas?lZGKR{O$(I2=#>a0fHpvPZ(r z%}srK`4eO=BO@azsb*c>=4gz*staYCg4x>IB9=_2M&BL0{9^wZ6Axd`(P1pE6o*4& zu>-G<)$7D|o0^%$N2{4v`hN!$0YzfLz9XS5Qd_!0F(}7zU_(pH`%I7wdiW-nU<>-u zqw7ccv1E^Ii%OUIZpUct1WZeGW~LOheU803E5+mcdpbK82TL$rUr*S!#Nn+Q#!5^3 zTUyj2Q1nas`mKtKCsc=flj@A;VBvh)}~uC)6$~Vu(yvJOgBXfX!Pb zb;AGw*Nj+x{VJ)1-N>k`tDBliF?{q9U_;%@jW>Gt=)W}?3Ue(b3weToSlImhDkOqz z8pC1s=&Kc62y$M?eIa<}L#)ni5{aZnof%)77B@06!9b0J!mLhP@0T(uv?crmY>?wm ztLw|R>*+M~^jI=4c;v1ezenQyg$rja@EOTA_be<3fZvLo{5*!sOY-eneKtq6G&lv# zy_OQx%pz3tWP@@Z)KYj++gFWyhHr9kBRB3r+Guxeq1nE_$Sc20CC$s7=pQg~WnYew zpVw2K4YKcuX;q$o$*1AzNzO78o$o>aYRX$08mMqEu3w*B z`?Kxi;p#r4x%FrJzS(0WNrPKK&_eoC8bdr6=e+1^t&i-Zy9Wo?e+X3e<=pQ803zeL zbQ4fRgZ1k2u;F04tmD$)Co!*)Bs?A;987gnhQh4h0(USPB0iLFr{9wPt*~$#fG4*^ z9H!*}K%8N?=);kUi{A_YCeoL`M|>;PQ=zRJl$BwXm6fBURL(L1Z0yye1O4|jIeB<^ zV0z36A}6_+!vzy)s6S?0vGvHjLeTPhhknQnmDL)P!p8&oc0>r^{(%9Ldoi&w%ooha zxl|PGGMY%|s|n^2PSr=l%i+_w_mrj#VoSUzWY$8bq3-r}=sk;Un@io4 zhuU(n1BG_eE%9p;Z}fS%Ki|6-BP=ZJxzH=`cn@P>VCCT807&fqO98}k6|(m8^n=}1 zM|x0psn>L(OOM=2O;c(BnZ%KMYNe&zM~txkj@;w$pX2ALe8 zs^%sg-7uQL%c0a1v1@j&f2-5LAza1jnt{Q1e(Mq-$y6vZyDe-U%A^^7O-WG>x&Z|j z@|Epli6Fl%A1Ig_oT8%fP@r^mdE(%>56vuG7`2pV?NOJ-%tK0X`JDJNw$(og;h6IPHi@z{Q{a}APlO(3P0Ps7M4@9S6U zY-*1!-Zam8CAVG-xUHD0N1?cHyq;=$KAB`w$HtaM*q)kYo4(x|Bme0qrFV>HPYU#X zSZ=7)X@-&*pS3BeSOs)iTAI@AXMz3F>eSE^{sJ|Mt99O%v_c&)c_O*gB2EpYG0`>8=HZf*{%sHo87 zcp@eZO+Y+wNsu4TpFiIeLmGVSfx#HSXO@Prx8SbjUmdVRqj6SNet0r6T|PNHjIVtW zVP59p=itx?%{7kFXz`5CW3j)&ZFU7Zf-N$6gPf|TG#SLl4-DY=Rxv>Ie-QRxH5eXW zNHxKlD8#;#$|IplnJ~z=ZGPk!f7`^w*vzb}r>Cc{1lt_r-iOW;6}sv;T<+fX?@o!J z=GY=`NBv}Wm=u5)AzyS~I^0Jf6hRqls(!D@34|Tt+iWx>Ux?{$_|wx9%;&!rn+kw- zx;a(>CK=Ru3kwF!t$`vm@Ay>7fd%NF=RUuA-W{WZGP2!{qw2 zSIW>thp=w8s1QX8{9h;l;{wGgffiV0@ca3`X`sP=KyLy4P5__A2jDzg7EKEGQq2aQ z@(zn@96l1QbCkc~l{@#&fKV%Tp_509MoUf+oY&j5BCKdF(Q;c~KH0W@XcN=8Q|Uk6 znL)6YRq~^*_xHzCV5OAU5k(OIQqryR&gV`izUYCJy|Hi?V27}RlX;QT_u|2+VwKS# z8^ANDl^<`S$8WMAGPmIyD&yT1n#^Gi3GY?4$uy;SrG+3erpjs`?pCQjwz|g7Ci8U^ zcb^5h80ngIZFX@{wB#>KNxmus5lP9)%DP{#DSSF^_nBT-3N_Mri-JQFM?5*YgLvS+>h+O&`4uJ6OWZ{NB zYwv&cS^p1jBmq;6d~t@53B7bUUXPcX`>oFz0UMo&bHSplh>osp084mhpIxGNhpxh~ zTSr)GoNN0}3~D)$OsmKFQqc6N>=QW4H?}$vF1^oC+oQaL@F5(7EFS%nW$MOe89QQl z6kxX@xy2JdUcQzfuHm&cz_130pDeZqK_=mrbuxJUm(kbNf_A;VdK9Rn4`Nm}#8>AU z7Alzc9Ee;zvqR=a9e?N#E{n}4jc3cOArV6>)c8KrbI6^@i}TuoIO0r7Ntq)16Wswz zn9JTJHCoW;a_ev7Ntx(f629x7#Ifsb@1C{tNSOMrJcrI-Tkx#uE1lyCPJ?bhM3*z@ z9I|9cD44~9?6Q$3Yp)x=hKNxots*idWqtxN&DIztZI*AlxHU}f>9e4>GPa4@=B}is zXgQdR+wZamHz(dy9`GI#teE+=?{rI|62{ibiaFV+Bw?qrMJ?bcrDdlRyvA0I%g16q zMVNQ?_U3pJhnr&)OGw?~^wlVaLia#}!blkrPrNKmT?7E907ov!rqzEnO3!btplvWJ zredPtjKI3ls$z%T7JpkYX$3FJWR!=erv;8CP9l?m$SPZShW2iRN<#FV#uh&AlYJcW z($K3_zr}OWf3+NKYDJI(5N%X2W(c~20tO@~MEv*KNuM%=yViFUALc0)| zaOU6-F9-Jk&y0S?2jGL9{T39@@{Rr;sk^RCsp_O?zM9zKb!?Qm&o$1Z{Cs9{hE7;6 zFWY2uu&0tIa_}G;pi^X?jYh<^0(oii zn1ENqEY&>Y8r~=@g05p>Xh3b@x#yru&t#NEe`lu~lui2fH19LM+Zl?epd8o9aR5{Y z+*|jSOlz;2HJ&V==8CxAS;2wmoCK;O{cgT3Z3Ar~rs1_YYQZF;8b?M(#A$5=Y`+O3kxRn1lVL?V4$nJsHMJY+}zwOXy!J0BtrE9 zcB2Wp2fi8}1z(S$QXYw*{{DWz+L&RpK#0>CfUtqQzSdB5piQGqTIP5~MwrtV%b7Rvr_>psqfW`@WENJn5nUaUG#8y)>errkG z;W`x01p|FGQH|a_8xvb?2Z#BeFF-{)Q3(t?0N~pjbs+07+XjcN1wIz)dSkNrrD&3+(n}J+H~I%bcIz2d&to2DC&fIU~--E|>Cen;t}Dqu7~Hia~a8wpJ0*|W#ocjZ}h zeuB>{BEIYPEJMNll$bG1gL=>Ht!LV&(XU zq=%hCY9A$0`vL6oOD^ki{K40=zSMVW2Xz}+t9 zC(?R=C^a!raU%g|%{uKwz>gOWIN{n}_-~E9Fc!fsyatI{H&NYhw1xt_QYjQRNZFvU zEon>pRo4n;|Lh$4EjhSS;50-H3=9MYmp~gbMy>x|nNGwxZERgOxpxl)B%Ck6?N;@z z$CC11W1)@T135)H7AHCe2DXfGq+y_bntduG;?)Z*^E~sL-+1 zfAviwb1p;PKU+HUM0|TB1QdQ@WlsWrX^V(E6t5?3Qn(KFsjmo40IhlrDt}t;u%0?7 zU2AFje#hS()Jg3Cwg`k3b-d$1el0H@+W-EX(UJq>hf{HK%t2T;W0tx>$c0dIY@1_B zoQ8t4akP}A{M|%KjTM4iKb>pc(0(g|<%@H)QiGe1v$IV6UmDawjIq+Ou+j+YmJ}D)wTKLuZP}6$@<&IYq@$$^Q!gHH;^?C zxQgy(u^hb1%43-EMqhnJ3hmv|p`X1tJA3!r!@sA5eijX`4(XiQryiBo;K_q1^0Nwk zxdS;2z|PRWm$?oK3uFIFk&3|iPCwFy!&l7|lK@RO^1^)kkcti2W0KuPzC2ZLxi`8CAThNNi{HYb= zm)kI?1d+I;fL|$SD9Qf5mgPxX0SPDErM#N8tf*>OhE)I@XaT60mx-F&AfOHQP@6CmIm zpQ+Q%$`dy$JS=XnsuJXKK3YE(nwgC;K?_n6FKw|dOcS|Qw!XNCg-H_<%>8bz2ZwMx;fJ?r?B^y-fOK7JK;$ME9 zsSaC^$bbxioO~|Dfnv@!0c@e{tLr>Y!`nKX_hDjy04+}aZ6O79vQ0~zO9Hewq6M&* z#+6j@Xzi>!F4d$S27TTFXT~{dMx>5cS64G3BqSt|51FW@)o-a$R8;g?tIyUzHrn2v z4sm&N^8v6!m0M-mB|yAF1rYP!jC^<6xMC%&lHA{ezdtd;v=2m8EYvb()3mf<=p$p% z_(@==8YnVRpkBkL=0K}I_9oOWafsfG9$sBbM7>p-AA2EPPMu2!66tF`h79`rTuQ9d z(rll_h$N-Z4pn;T@Je1(#YDTdbOLnOE%9ak+v6&D25kTshfxmm?N6tdo%f&_<@07Z zkw2uT(sW$c;NUihcOb53FASDA%w#wYB$(xnZ9@`w$o5+^8Fn?BiiDc+oWP(dm;>y! z-MGU!y1mxwSFbYcLnGlp3wT$d8Qf6R%7vR>GdmrvgWo8~E`>n?X90AqaPQ)+6d}#( z)b;zSnpc*h>2yuozqoL*S>>xm=G$ZG2ZdvAXPc|7i=13;IwiCDxRx09GOBVr+1S+O zu7N?vr-&>OYKov&=l2P0_&$H9y%7~ep8U@7!&&R^1{L?Y5G`eR@qX&zV8?# z%;)yGqUGntX}XKLs78Jp5oDlyH>sH&ti8!Rq5_Ly&#flEYu zdkw{Kz^CsmPJ1lv-O$xzy7oHTchZ50BE~{bl+Wr`D#*w<4>%S@*fS=uZkNN8Hfe8M zy6@Wg60t?}hQ#tRD6kQX%|)U=S%tu$^V*uz65YEG6b<_fz%)*9p6M8`=D_(6x%VVs zm)3BrZ_4CMz?V~FL7N)|MB_`yW8G5SyWK5V+%4ZzKC#*;O#`uc8&WV7)4ptf(rKx7ukp1uB4d#!Y^l23 zre{$XO`Ir8kTO++oVONH>PyAPpf~kzG4W!eo_Kn95gyZi?F6t?Yg+8)Q1Yy-#u+q1 zc9A3YLQoE{`Ar*;?Nut*R-sl@GU0$k5X=PTXsqT&&~#xQE62BZzw=diClz_Me8I+; z;4|+CwHwL=(D6*dV^SK|_xtqhVX{76%eYCX?i)@Pd~Wc>(J)*ox6?*ygxo%q@POYd|^lnv|92aL;<5z;7Z25u(j)EsW%O){X zC4u2LPa~uFG&bpEob#ZIc8k(<2CJ3OtW1IgxHit_*zF#)z2Zs6gII2Adu$QdflRd5 z_j%2~TH|gW;}1Qz7zQo}=9?+q>a^KbI@nsqp@@ESo%~u8p=^Smz7sfoC6YJ4$}0Mw z>F-}YDK8M^FRDUc$__*~tu4a;OmxP*()CSfl~%#q5Vf{%_$sqE`;+*Au?Ex!{bG$> zm=707Cp6@TCb&j6HVUKg>$QMU9D&&VdL67ykfkvbwIHit08-K?E%0`e zzW@@dtpKa=2;>@xAYj>aW4pKE8B#LQewd9(Af@wtNN<#~UlUXE0Do2F=B}*N8}mBe zg&%tQ`v5oy-9tEHzpq4)94~-B~aD zS8K>kE%#o6Lx2~wAKagBJr%z2c(+7`NfACbcN7qi{(nvE7~VZ%tB<6kb*ynpd$l$B zLnpr2?epg9%a#)eeFdp#%?>aNgHE&{G)!>&V8%f9i8JPp;ay&n8B>=lxJKax1m!ldwCt)exx6)_Ia! zjSJcvB%X*h3CK>lfW4%>s-MR?QM)e-nt6e7L{MG*MxdWMG;Ob@O;B?M?Cg7n?Qyta z`R$zv?T|or?Ii2q2b$vCXAbuNaaQbyltK4yx_Xp9X{I8w^$Wya;Pf5*bln%!p-<}X zSA5h(d^|t>cTQMVs=63W8RbPMp0lFbM47#&(mDd252AR@qS)}$@xH{Gbtr#x>c8ot$_4$1|QUZylo;+;Il@BDY`4={1(D=781(iH0eF9*+D1y2TK|j|9#W%z?wdcR*Cdsdz5kwToW~_be}{GFo*M z-{8Y<4G}H;NJbDamod{~?z72JrtV$)2=ool`fuX9RZAb#$)wQU+%z+zh2S>3K_wUW z9L$AWPlAq&NhH>Clc0LV!;_CCY}Wyk5nj5QU!^X+oGI;_X@aJWHkx~oz|6EuBF?!c zZ{O*&KRt<*KS6iEDDwY4xQ`w^Vl4A!L&(rw>ZQB^!o*Ng1Q}nn{K6-Fo%T}LZjI!= z>{+|tJ0!Xh;TT9H?K*L0YdHj!V_A)<%v79?%U1{1^}K?D9lm_*c_TQ=$buL_#HJcB z`Svzg3H=+i&D}^{#^9eKluRdV37)yLoWxs!ioD8{9-!hBfs@ml_or&OQ^{l*2)wvu zj-Ia0PSx$@BjC)g&=o{*rBdy{-Gsa42aQ=AGw<)J@ zoA$QLWQTb_VR6!z)?DA#u*0~EyH(%2c&l?`dQpWt@jbwfF{{Mm z$3K1hprH6t+LMgNKs_|a``$h0$#P>qKRC6eNJ0U-qr3}Z^q4hPPUC7K*6F64*d)_w z>%6^E50**slcbB1cc(f+p;+rj`5X#a&J6j!Jo1zr^6KZ+;{wr|+(&nd=(1SGePCg~ zegq6sB!_q<%oMPl>rhfa-|Ns*A+>8;+?eP*JlRqt7Jeg=O943!-PUz0P-bVUE=->C zqfAQscEo1s9)AO+kO>-GVdB5_xvH~=;G=jrM9fme@)mT3I>m9?AHgc%t*hH{rQ$5I z&z3lxRWFA90pW90Waq(?VW64b;$;copII6<28Y%PP;&O*bS>-DL_Y5DATEK~CBO^j z{CVIRKq&(gde!Ia$+tkg1fx2iGz+&*!a@<#?*Od9TcQGu$9 z4Zs!KiU+gsML?%!-!XM7g7u#muuJJ41`CzQ_Mg_bRdr40l-7=_qdrs7%@q|}a;f=r zB^fSm9Wgk3%F}FD*=+0u$9t8YXyb-pwkqq{xw-yg7e68V!d)8c8_*a8mVQTg=!k3z zXmCD#I@^_Q3;^f7wI!kx4vPGVMALXuR+J`Pic@`u(1$Z1p&y0TIe*0QVV}uVC7?Sn z$j;4oR3Y!uii*ha3~cEM;?ynFe8l?B;}LMJ24lZbt&W35*;|oXVoP(Y4e-$vAhw~0 z8!pOL*~+GwGWH`n!9QLf)7DmFKeT(+O*v>?Mk0vq^jJG+8T9ST(ENd?Kyvmfix9`G z8#NkCVS~lsj^h>OIHy{4Xy#*6Fn`3pe}ds`4S|ErS%mvMknO;ca^_CX!|seeS)q?Q ze+Ib_JzSnvNI`Zv9iWf8B#P*0p6vW4)e)+3U= zHx|YCEB{91^i(5H-f~alsCxU!Jz6pJ(pZ&Bb-O0xMsf%E6;nHQ@o?Wr3hqJMTJcG} zOpMF6RI3)chJ5mhHjHK$qY{5|ec)mLvR4z=EY4rmXA$M>{KK+0-Be%c2@)Q?lx&zc zr=YgLCL^0)t-g=#<1KD3^V5l^l9P-p6a3E!RJFBL=+a-D&Sqyn>G}OOikHA@@Hbw;`eyYG=e>1l*qyt^ z&#Xze1agb{PfbK{1h_=T}GaRlR%sayE7k-R57nJoSAI`FtNWe(pMM z(LMjq!ZF*+YWwns<1W|oSG}`8vr9tZ!@ccvHsoa#o3vZV1F!X{1G2?=yGC{!nzrqi zBbXQ-n70G<`0qB|m@U^?fGTDaaXI_i-d#tGV-C+1Rb6fmF?UjBhh;0{Nk5HKLx1En zinix!Vro9=aXO4VKN@iQ*F#b)y1Pdr8$rJCeK+s0B`q)Wt2^Hw{?%3WP75&(zd5g9 zLEYb0@krIg%Gu z>Hk89@SxO~j}7GDN!4DXCH|J^>Sw7>qmW>r3XS#-jhdv@d*y085R z=SPsbt{kPKTx|@dief-7YCtyU;RAIqUkRL zU++N^1-sUDF6tw@F!EIv(yDJg~xh!x@zTI8(EzjmS8PD zGwEHJyf*DLoHk3Q~&zQS%|AflO`pI zEW_ufYb!`=$1PvNBC37v1@T=yIhIr146zNdk^5*wY-5Sw%kks+^us&jk$8h+3C&1U z^n(-}S10lJT@%4_b)&BHe?Q#;!Ib_eXZlMRBS9%%tbIsX5x|56~JjcxE&7*;`JBi5u_xKKVxj~Sc7%83P}LOYRUVK39zN|P_3ha2z31PPT92gSIwXR!-glgM zNv6=HEp_VDv|#2MLHo8Gp>XawA^+6P15o@np0u{t!T?%4@QMaJKXqdO@+NNJF>V# zj4DH#sCxz!ztM8SU&>#@H6i-$pE7Y`ll>Aww6GU-n2T^JE@B6o?(XB`o>V=aC#Va6CVR!L5L0$+5c-R-+QC^_@o?J6z& z@la%9MT}lZ;GBKD+}XKI3z<_#RBy2si%ilTbz8oJkB90oaKabd>o;1c4#DPfypv9) zBhwP^T=q>z)1~tK^KJbELPas=ohB&UgJ2~Ic;=^9A7Un{Z+1Z_YAK8IhsrJuKMBtE zJ?ngXs&Q#bK*cWO!`s}j6D+3wSHgzVyvya8aX~rZ|DvMmtx?mt;8mTS;u!?9{IkRZ z{=GS?hXPJNo!E&4gc?W)R8n9xORg?aht$cFeg*l*Z36^a>JRDKTQM#=9s{e#xXt72 zta|#KpX5oy^1js5AN`*qSwctryW71BVVIRBumX>3%l{SAPUJ<+bzx2?+Tn9D<`p!%<=f==DQ#y3$ZC-hl~7m{aM9a3(Yw%6&IqneqK!Fz>%1}OyS_r zy-yNuUbE1(#FBbjmA%q2?1hzy3KMiky|J6`i0|)jZp6k^-uOz^ScI z0d=mUr!r^8QR2Rr`g*>6_-Z&Fvyts++ckt_?^$^2x{6&#!MWNpr$ThM`XNxoM=IR1ESj{Z4RrzAQJqyFbm z`=6N1#TC)1IT?;OYNK8khO}nsDOG|KtF{+Jo+i7t@jLY!L>y=A|P z+2nABnb(J2`ZB<1`pj+n`cL2E^^&4!9A=h&{DH_ZiGb7BlEw3QfKfDY%g)u(<0@J# zPuwc(3BNV^#FxKDk|guJ^FQuS=c-EoCR{LF(9WkCwxdt{!pHk19iakAFKB{Ar2$pnTW-v6qiBFoNdEg_^H zW1alRAU5_I6Ykl`^=-lDqdy@g^kB#5KcFeMp<;LG@=<5b(Am~u^KPCq0jDoUXH>wg z$=7Jv`E%u{vZ>qi@RQyZh-$J{Na`#00xqC|CPvds57W?kQ{#=d0 z$G?#|2pzhGykA+cV*}$s*~=acUW2Bi&I#=PPTKP=*s07dosI;p6CNMOQ(*~(Wlh%t zq2E{~z4H@XOImuNr*>M%4gOG5141YtF#K0jF>(G&{2@;EL+%#ySzFY(sfAdN8hV`- z$D4vTn|yUwkf`{$);5hfawgG9$>zxw80CF1D#5uHX-z3l1VS$E&tOI z@@xkCp6IZGih)PiqG!%MJHl|LcUaYu!)Ti6yiP*>=0&&;uW%qEB=yW%gBM6ueRlh3 zuYI|*hf`l)N_h7ByZ*E(SA0RPs#qD4B~y~<0Y^ISEdo@)*+*Lm%@{rJOJ*x|F*D!& zPs!v3YKC(sw5#YMQHiGd{WlY=o8u>`N@mdEw#BH3i!B~L(ruzQ`%5^zT%aF<#R%lARtawIO2!q%i3ee35yr_Ix+5PEv4yTS7lFk4)-34tk>7Ss`go}Yj)}4HaOm#-w%(SqoZi(f~yst_fFbT%JIN8 z1?Qjg`+Q}dYUyz5w~6hqGB9gNwcRLuk}l8R7nL?Uq~u7>u5)<|!-tRYWPB||V})|@ z3aK|O0;7iP4(%gUQBt31dd%BqpBHmkGNc>{Xf$gHC6uGE9m@W*K_;P-#J+U{>sr)3^@7gd!xYilD>X*UUl>Z-vZ__$nBH$>G@pAZ<-C&URQU0C7Y$B@}xEA%(M2&|W)erW5%6y_evCaCX zN>ebF)TH2mUGwWzKoG;ce*9wo1;SgUcsmVOuU#kj@BjGGo@9KI(lj+Hskr(e^w6h)BZj6Q@W+`uYSqiUa?v z>fmW58xUxnabXN|Q<~VO4=~@FoYA+-r(zuF1jbg>T8m0i##Ept{VqZCcu;D~qv^ON zBq~f5CFXs?|9g^L1!X#rx39Ou&DV2n6(78FT;>6UT_gm6F4kDV4HaD=h22kn6;`qz zC8$CZu9Ia`m63s^)v$NbSPhr-_C`@9t;Lhx$HuFw*fkaSea4_#g7MgSNn1~pwK#6V z_pn%LZm(EN>5cF(2+F&wV&h*o$C}qh&shEJNkaBWyv4DhJgaXUe~~D6Ch#nFr~jQi zl;o+Gn|piX&8Yai z#)SM`Bd)KfPkH^+GMo+_zEK>=+dOiL@eQcUo7@b;gukYz(h0lnZpU@(MUTi7a(wvt zd{pzb;&kGzzpCCzY#lK4Wt(msc|{^W6Jkd`nsVd*ie>zxYxRY&usEJ|=3wzm-^i%3 z)N-of4(I3wa+C1JZTi?j#h2UHT1cm(HS|rNaU)gMr#9T}>GpN3B`OPznod&WhjsR1 zm^lUKIxn^1c2~ZPJi{MTGufr})DzG;iERMl|1!LQ# zoVH7TL9{SgtYzk_wi>d>;Be&6wfXm#y3aVJp!20az`iKnwqm^>ykk;A60$;^#8aC5 ztJz>*yGCKNBjFBmuGrD!76Fq=@Z4Whj>peumB9{Y5&E$g7GYztUq`KtjF`(UWbYd7 zS5s>Gc}~CJ)C290jd!X~7zC2pP({ZkyiADyWT$p_>_d>!H zzxucVqcHw91spp?*_Cuh@{lJ3Om@khm0Lp+LEx912ZPjDdvbj`A=Gx4+cBZWdo!=> zRxm<^^u96BQhym{rNzeyp8Uq=^TVi4Lf0TI&?sHZk2aqTIY;dJ@pRZC0M?%*$hE3s zXjBr>kB9}^?MvqNYVymlC~4on&TJv7XmT?yS%Z=u#)6zIX;VH&kjQY2i^Ys52?`~i z)J?u+7w=xz>c6oDi!3f3j=s*bO-W?*Rb6B-@3|2660xYH!v<2Y#y70dFY*nNCGtts zQfiu_gxal0?&7u6feL%zO8Tg&mVb+K`tPoKm+P={hIda2f2j3T1s=AX+1S_s|IR?G z;`mE2TF=93!zQ^z6qpLlJ?pRTd19orTTI}z$Yz76M`RKiiMUsD8`8`T+ud&HlZXAj zd*LR~5O#FmPnQmtfLRT8^+St$Pek(7aG*9v>2x|+1zgItg3qy;+CSg?n0fAue_{Ut z0AaFoWjNl7-p}1=J@Bi8JtBJRTB;^9-exb>3jE}DPHs?YRarPZT9QbKi#oXB!MT$g zxp?4|twLfKOp^Aqw&Ovx9jwTWjpuQzYR;n# zSe`RJC!&$8JGJu8KNI*`d>#Abn5bx3IAF~}JN&jRi)q92JA3?o*7BO3USmA%dHn-2 zzDtP5{OF~O^{_xB%h#%D| z=~eXZc+7=cTz-?;$U$WEEmKFxpn8CuvhA^dA#4y}iwy(R}BZw3W);CzE|6Ye0 zbr7iw!`)`F^aWFMVIlZ89}w16zBai&eUhSW6CD8eAHbMSfgC*s2siT*&kub1E+>>C>5<@^JMQ-S0P+BO ziIIPF`p2x(KeCK){`r)=eAgRyEdljbZsZ+wELDG{eU15yWMviZIEaM9GW>uevi4>% zI#gp}_$TiApYNYor=El}XfWHLKg(4V55x8pHB0};I2g31f^`^7m^H^*N=9bR9BZZq zFIAAOOM;ju7rRdmyTuT&5;zwmGx6U)Pp${RymNA=GQ)}xkk34TXP%_o4SfIPjvzyb z7O+$2t}@lj_t2f3`ucjUr@-yp1uh_+D}if8h3my_g=@tb0zhYE$*jD0?;fYEQ>d2d zh1=Gi+-n&ZG=cmU1YD{ETskUT{u_8^!B<6~{wF}yJ%Mw<^FHu|f`Wj*Ob04ffsXN7 za0$45ZrwWISqinlHF8(4h9>XI(=y!vTp8!Sm#Lu>7(WS4U%q}VEhzzR%`i2&0$jD! zQ}q)VO29KOs;aBi6LS~@)PW%*tUA~4{r&y*z}-&3Xx_SYE3lNfdiCV0RlxF7(8*&t zd+^GGjg28dhsDR|Yo#7EX7JGgY15nP1w3y|=Am>mV}tS&g$Q8nL+N0^Kl>X0ZfB*$ SBO8H+F?hQAxvX^r$EmC8SLyOC+-PP*F%FB+HOciLquG45g$*n|>oV`}dkYpZ~tg@jbr3?=}C#`JsTsK_`dxB^PJ%frO#N@$e0X z-w#nu&TRO!SL%s*)#c1x#U<$$x&48^`@2i}`}t;bbBo!Rm(ISq@xttK?f!!@XB&fG zIjZ&DJB4n+lVfBOnig8-?iE%RX|^#~zl>aP-r6fkeM%`>Z9%dH9wQ&&2@n$sRx>>C zZ_Ra)8u;gIs#l{?XHSnwymE1Qd3i-e#plnTKi=e3^FG$q)78~AG&I!RUE zY43+$)Ej=RaS4@>kcc@w`EGKu$?^1uf^ROSjQ(O*>Rg}MOc;DeX~s*yWB<$RWga6r zRtC>mq4k8f^46C5c1f2qjI>4I8|SY?ANm~|8!Mam_15xuVbZ#!eRodU%*>2Mo=xAt zfb~oP_cAy5Lq4dzG(2v#{R+$Zq?)PDNVw>$rcKNxXZZ9ViFZLlVhYE{gju_k0=zmN zY;1TFxC1_jdaKV{R^WN{U<#x4PIr#g^XJdgrMR<@Hu?ggGx;vfNHyB?yA)zy_~KeV zhxBx(Y4EIdX*DI}o|m7$!m2?`kjzr(5!re4B$4mwadud@ zfszB|nMBr*B{GEO)F6$qF)}i8Az_PMdstKq2d7D9UYQ(x|NebX^+IvJ|4+F|e3Gc% z^^$viE;=iHNY+e29k$jrubloI6~y{u(3WyCGqbW1&7yD7r8SviSJU&yHSdp^s8vr? zlUW@+5~%96u~K3PS}?Vwgp!L2ZYDGFu|>|3=H}*b%RD4=R4j$V6zj>e^*hMefH)lf zkVnhuSLe;V-|fm1k0tE9+b_s=cXvzGv*w97%*3x)BE4JEV13eY)i_?+iHJ4f4$oN6 ztes!ot3%JI^8=-h4fxaE&MEhAG~dZcI_1{inIE#It1pD#?2U1zvO_)`23&=Ik@g%vm<jhFW_WvfD% zySuy8a=W~|nGU5uI3-|mcZ4NQCcMADzvGhTd>e=P5I*8hv9_`*zWwK;Tz=K^FS&f1 zDt}KWCttk8?!ISRV2ODDiQx~8oLQ(O-zXT(Y{Rg<y*hy z!=14Uz9v|ALBo8Q z`~GU;dh4Z_%6S-&YUXmBUGQ45rLC`t^H^p^vaSidyxAzQ6(KrQyL%Ycl8j<--In}2w{NR2 zqjU4~G4rlSR$p64NDbwYkl67X-;TUA3>S&kWv}~aRNw8&sv~IBi}d1KiB2Z(jEx}{5qPUMd?+%n%P<5JBwR-K7iw}$kes9Ms9`L z)UZp)q@*O5l;HblG(%QrNtm|l8sC}Ir^Rc!y7Wz7B>S{S9`J3DP4a0UelE1@c;o6_ zK^X}1>mJ7VTaxhD`$Bn+5MceMLo&+GCqF|ny#yWR`+ZHdi|5{$T?*+)Ab50Jxfs9i zd_z0vA?PsKlD53jBTS;@_Pu-RAL6@$`zh`P$1E=1=)jrY8zT7SLTM#mB6F?wIzg8WVQMu_(FL zr3yA>U(?bKm}SU>%Vb>lCfL_^nC5FO{V>CyCNYJBhV>zm)QC)qguB1VWDYko_+eLs z2{gQ}|3W!Q**b($#8AL7)5Yxkn~acwU0s&AIU1=nLd1?kmrzEo`N5J1SV=(Hl)AHG zE$xEYG$ZN2sga^K9Y!;feKRt%KHSL zjseViohGC0uG^6BY_2q>$tX{qwOYgthn64rkVqob0%0;gV}7WT3d1r2_j}bep2BRB zr@7y4eP5iQhH6SAe08Wxi_zJx_vOnMSbOKq&AS)`D>Vr|5-pm%7JWD*Z}>ISk#+ zGR6s~R7t;%BaWyD@Ren|a$dx-yGs{(OHss^#92Z$8iiw7KP=6+t9I_nG9MbUg}-fD zD=qI;UA^ssZz-NS1FQaJ3~y+pYeTf8OnAV`r1`aL2VXbI<&{;f&n5>`to#N&8JQW_ zsmzSGwiuSHG}qUubhOC#I$;j;yO3hp`e-_l zwIGS6mOw&}mkD=Cwkp2)^XVuRfiS)-z~@iGCpGN#UVUMC+igg7eX4chR!?41x)d+s zKt2|${Vnk-vokj+b9XSX5HYK1 zm0k*;eyz8-uvzJf)i;+$@K+;(%bE^=P$!LgrnXelYq`09zb)T)&vHQe|iMXNH8 zf0g40s{)$>Zp)IrMnrOMGVnjE>usec?pBHq|LF5AfP#VCDrw)BJW~-9s56YU$=S zKb?_sf544%!`gbFyZipgBQZ^a4B|(oG9vXp~Wh4Nii*FjtCQo7Y@e zzmyrlhj`N>WAs5^F!Jo^r`MOBddRFU458mDA_+Y`mj4Chj=kawxs=f%XPI};b-?!3 zpEnm_Wx^ocU;& z8xZG>_P;y=W2GljbEe5DgPgkicqGr^FAvKTE)ZLgWM%Oqr+GHNF}7H6zC=O2z#>F% zOy)2B2RAPZ?mtjYLQD@l7{aMWveSQFL^!G>GZ3b_vd=60y@|% zhDuU`;XysagWDBz9xZTi?a`u7ULg4EJBR7>x=F@|CtDLRomYyg5Ah!1oAwE8e%mUc zmPej7qWb0Y^IvSd zu1XI=HLmh_bKEsG?8MvSYlzUPPaO_tSf@^&O!R4g)~R@gcIRHA&#$A3Sx}uhnz}1J zxC4^Bhh##-PPF6JX~P34eBL;tw~039PXGRMCLk*>&#G|zM^;vrzC;;kO8Ba{xF)Z- zxY6{S?zE3ays^TKZ`WD8Z%Suo-v4}NYJB*0JipGWa82(v7@R5HMsG@r$oIkWmD$ zSx!-P&3lO9{gL)@|7jOIQ^{ldbv{1F2GT<46~C#31Tl6K4j@yUFj{*&G%Bu%Q;fUh<$# z{~v_MIH0^&P5K1W!>^k@f4;CWU-|Sc7U>K;|01{l)0B{QNZ|7Y=&0d>$X{&Hp?( zOyo@aEH)wSkH_=yUrZ}p_F(hm;X?EU<>gJxJ{wE@`Ikp&W-FPD3Ec*>*{&Xy7Tn!= z?eo7`w0b><1fHglt&rV==ac_bawXs{{8MW^@nI2WdH1p3{sdtNOJtoBwftH=ufEbQbCI(U?=dJ ziZ=c&pDsKH?i$}W<~!SsB4SsnR`AIuryog_&lMW!2}04tEH^pHg!dK2yjMeA(%0AD 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 diff --git a/docs/runbooks/gnome-qemu-desktop.md b/docs/runbooks/gnome-qemu-desktop.md index 7bfc0639..8e7372cb 100644 --- a/docs/runbooks/gnome-qemu-desktop.md +++ b/docs/runbooks/gnome-qemu-desktop.md @@ -177,6 +177,53 @@ Gvc-DEBUG: Updating sink: index=33 name='auto_null' description='Dummy Output' El `Failed to connect context: Connection refused` desapareció y gvc ve el servidor. El sink es `auto_null` («Dummy Output»), que es la respuesta honesta: la VM no tiene tarjeta de sonido. +### 🔊 AUDIO FUNCIONANDO (cerrado): el muro era `libudev-zero` + +``` +Audio + ├─ Devices: 48. HDA Intel [alsa] + ├─ Sinks: * 52. HDA Intel Analog Stereo [vol: 0.40] + ├─ Sources: * 53. HDA Intel Analog Stereo [vol: 1.00] +``` + +Y gvc lo ve con perfiles reales: `output:analog-stereo+input:analog-stereo (Current)`. Ya no hay +`auto_null`. + +Hicieron falta TRES cosas, en este orden, y cada una parecía la última: + +1. **ALSA en el kernel** (`linux-metal` b3:613bca15). Estaba `-d SOUND -d SND`. +2. **`wireplumber` + `lua`** — el gestor de sesión, sin el cual PipeWire acepta clientes y no enumera. +3. **Parchear `libudev-zero`** para enumerar devices de CLASE. Esto era el muro real: SPA pide el + device `card` (`alsa-udev.c:178-183`), que no tiene `major:minor`, y libudev-zero recorría + **sólo** `/sys/dev/{block,char}` — o sea sólo devices CON nodo. **El device que SPA necesita nunca + entraba en la enumeración**: no faltaba una propiedad, faltaba la mitad del espacio de búsqueda. + +**⚠ Y la primera versión del parche, que recorría `/sys/class` ENTERO, arregló el audio y ROMPIÓ EL +VÍDEO.** `/sys/class/drm` no trae sólo tarjetas: trae los conectores (`card0-Virtual-1`) y un fichero +`version`, ninguno con nodo. Al entrar en la enumeración, mutter los toma como candidatos: + +``` +Failed to use linear monitor configuration: No available CRTC for monitor 'RHT QEMU Monitor' +Page flip failed: drmModeAtomicCommit: Invalid argument (en bucle) +``` + +Pantalla negra con el compositor vivo — el mismo cuadro de antes, por una causa nueva. El udev real +también enumera esos conectores, pero les adjunta las propiedades por las que mutter los descarta, y +ésas libudev-zero no las sintetiza (su tabla es fija y está orientada a input). + +**La lección, y vale para cualquier reimplementación parcial de una API: ensanchar la enumeración +expone los huecos de PROPIEDADES a más consumidores. Los dos lados del contrato tienen que crecer +juntos.** El parche final va con una **lista acotada de subsistemas** (`sound` hoy); agregar otro es +una línea *y* una prueba de que el consumidor lo necesita y no se rompe. + +**Por qué no eudev**, que era el camino que parecía obvio: el repo ya lo había probado en otro frente y +**rompió el input** — su `libudev.so.1` pisa el de libudev-zero y, sin udevd corriendo, no expone +`ID_INPUT`, así que libinput ignora todos los dispositivos en silencio. Verificación A/B en QEMU: eudev += 0 «New device», libudev-zero = 5. eudev sin udevd es PEOR, y correr udevd contradice la arquitectura. + +Costo del parche: `yupana radio libudev-zero` = **51 sellados a deuda** (9 en el cierre GNOME, que se +reconstruyeron acá; el resto —base, cli, KDE— quedan para el latido). + **`wireplumber` cerrado** (b3:39a9a06c), y con él `lua` (b3:e6c35f98), que hubo que autorar: el Makefile de Lua **no produce `.so` ni `.pc`** —los agrega cada distro—, así que la receta enlaza la compartida a mano desde la `.a` con `--whole-archive` y escribe el pkg-config. `-fPIC` es obligatorio: diff --git a/recipes/libudev-zero-scan-class.patch b/recipes/libudev-zero-scan-class.patch new file mode 100644 index 00000000..1ea0ea0c --- /dev/null +++ b/recipes/libudev-zero-scan-class.patch @@ -0,0 +1,96 @@ +libudev-zero: enumerar devices de CLASE para una lista ACOTADA de subsistemas. + +EL HUECO, medido en las fuentes de los dos lados. `udev_enumerate_scan_devices` recorre +**exclusivamente** `/sys/dev/block` y `/sys/dev/char` (udev_enumerate.c:281), o sea sólo devices que +tienen `major:minor` y por tanto nodo en /dev. El udev real recorre `/sys/class` entero. La diferencia +es invisible para casi todos los consumidores y letal para los que piden un device de CLASE. + +CÓMO SE DESTAPÓ: el audio. `spa/plugins/alsa/alsa-udev.c:178-183` de PipeWire pide el device **card** +—`/sys/devices/.../sound/card0`—, que es de clase: sin major:minor, sin nodo. Con ALSA encendido en el +kernel, `/dev/snd/controlC0` presente y `/sys/class/sound` listando `card0`, `wpctl status` daba +`Devices:` vacío **porque card0 nunca entraba en la enumeración**. No era una propiedad que faltara: +faltaba la mitad del espacio de búsqueda. + +⚠ POR QUÉ UNA LISTA Y NO `/sys/class` ENTERO — se probó global y ROMPIÓ EL VÍDEO +La primera versión de este parche recorría todo `/sys/class`. El audio pasó a funcionar +(`48. HDA Intel [alsa]`, sink y source reales en vez de `auto_null`) **y la pantalla se puso negra**: + + libmutter-WARNING: Failed to use linear monitor configuration: + No available CRTC for monitor 'RHT QEMU Monitor' not found + libmutter-WARNING: Page flip failed: drmModeAtomicCommit: Invalid argument (en bucle) + +`/sys/class/drm` no contiene sólo las tarjetas: contiene los CONECTORES (`card0-Virtual-1`, +`card1-eDP-1`…) y un fichero `version`, ninguno con nodo. Al aparecer en la enumeración, mutter los +toma como candidatos y no encuentra CRTC. **El udev real también los enumera** — pero además les +adjunta las propiedades por las que mutter los descarta, y ésas libudev-zero no las sintetiza (su +tabla es fija y está orientada a input: `ID_INPUT*`, `EV`, `KEY`, `ABS`, `REL`). + +La lección, que vale para cualquier reimplementación parcial de una API: **ensanchar la enumeración +expone los huecos de PROPIEDADES a más consumidores.** Los dos lados del contrato tienen que crecer +juntos. + +Así que se agrega subsistema por subsistema, con un caso de uso medido detrás de cada uno. Hoy: +`sound`. Agregar otro es una línea en `class_subsystems[]` **y una prueba de que el consumidor lo +necesita y no se rompe**. + +POR QUÉ ESTO Y NO eudev, y acá el repo ya tenía la respuesta escrita: empaquetar eudev se probó en otro +frente y **rompió el input** — su `libudev.so.1` pisa el de libudev-zero y, SIN udevd corriendo, eudev +no expone `ID_INPUT`, así que libinput ignora TODOS los dispositivos EN SILENCIO (`udev_assign_seat` +devuelve OK con 0 devices). Se resolvió restaurando libudev-zero, con verificación A/B en QEMU: eudev = +0 «New device», libudev-zero = 5. Ver [[mirada-usb-nvidia]]. eudev sin udevd es PEOR, y correr udevd +contradice la arquitectura (arje-zero es PID1, sin udevd en el camino). + +⚠ COSTO: `yupana radio libudev-zero` = **51 artefactos sellados cayendo a deuda** en las cinco +imágenes (9 en el cierre GNOME). Una variante NO era opción: dos `libudev.so.1` en el mismo rootfs es +exactamente el choque del episodio de eudev. + +diff -Naur a/udev_enumerate.c b/udev_enumerate.c +--- a/udev_enumerate.c ++++ b/udev_enumerate.c +@@ -276,6 +276,37 @@ + return 1; + } + ++/* Enumera devices de CLASE (los que no tienen major:minor y por tanto no aparecen bajo ++ * /sys/dev/{block,char}) para una LISTA ACOTADA de subsistemas. ++ * ++ * Por que una lista y no /sys/class entero: se probo global y ROMPIO EL VIDEO. /sys/class/drm no ++ * contiene solo las tarjetas: contiene los CONECTORES (card0-Virtual-1, card1-eDP-1...) y un fichero ++ * `version`, ninguno con nodo. Al aparecer en la enumeracion, mutter los trata como candidatos y ++ * termina en `No available CRTC for monitor` + `Page flip failed: drmModeAtomicCommit: Invalid ++ * argument` en bucle: pantalla negra con el compositor vivo. El udev real tambien los enumera, pero ++ * ademas les adjunta las propiedades por las que mutter los descarta, y esas propiedades libudev-zero ++ * no las sintetiza. O sea: ensanchar la enumeracion expone los huecos de PROPIEDADES a mas ++ * consumidores. ++ * ++ * Asi que se agrega subsistema por subsistema, con un caso de uso medido detras de cada uno: ++ * sound -> PipeWire pide el device `card` de la tarjeta (alsa-udev.c:178-183), que no tiene nodo. ++ * Sin esto `wpctl status` da `Devices:` vacio con ALSA funcionando y /dev/snd poblado. ++ */ ++static const char *const class_subsystems[] = { "sound", NULL }; ++ ++static int scan_class(struct udev_enumerate *udev_enumerate) ++{ ++ char subsystem_path[PATH_MAX]; ++ int i; ++ ++ for (i = 0; class_subsystems[i]; i++) { ++ snprintf(subsystem_path, sizeof(subsystem_path), "/sys/class/%s", class_subsystems[i]); ++ scan_devices(udev_enumerate, subsystem_path); ++ } ++ ++ return 1; ++} ++ + int udev_enumerate_scan_devices(struct udev_enumerate *udev_enumerate) + { + const char *path[] = { "/sys/dev/block", "/sys/dev/char", NULL }; +@@ -291,6 +322,8 @@ + } + } + ++ scan_class(udev_enumerate); ++ + return 0; + } + diff --git a/recipes/libudev-zero.toml b/recipes/libudev-zero.toml index 2f48be36..43d61ee7 100644 --- a/recipes/libudev-zero.toml +++ b/recipes/libudev-zero.toml @@ -1,3 +1,11 @@ +# ⚠ LLEVA UN PARCHE: `libudev-zero-scan-class.patch`. Upstream enumera SÓLO `/sys/dev/block` y +# `/sys/dev/char`, o sea sólo devices con `major:minor` y nodo en /dev; el udev real recorre +# `/sys/class` entero. La diferencia es invisible para casi todos los consumidores y letal para los que +# piden un device de CLASE: PipeWire busca el `card` de una tarjeta de sonido, que no tiene nodo, y sin +# él `wpctl status` daba `Devices:` vacío con ALSA funcionando y /dev/snd poblado. El parche explica por +# qué se arregla ACÁ y no empaquetando eudev (que sin udevd es PEOR: rompió el input en otro frente). +# Ojo al radio: `yupana radio libudev-zero` = 51 sellados a deuda. +# # libudev-zero 1.0.4 — implementación de libudev SIN udevd (lee /sys y /dev directo). Encaja con la # filosofía no-systemd de tawasuyu (arje es el init, sin daemon udev). La pide `libinput` (vía # input-sys/libudev-sys de smithay) para enumerar dispositivos de entrada/DRM. Provee libudev.so + @@ -9,6 +17,7 @@ version = "1.0.4" [source] tarball = "https://github.com/illiliti/libudev-zero/archive/refs/tags/1.0.4.tar.gz" sha256 = "10148cfd6047d387bf71eca72cd19c177084224d96434a118d8def6e0a3d6316" +patches = ["libudev-zero-scan-class.patch"] [build] compiler = "zig-cc"