Linux diariohttp://www.escomposlinux.org/jcantero/ld/2015-10-28T15:24:00+01:00Una apuesta por las licencias copyleft2015-10-28T15:24:00+01:00Javier Canterotag:www.escomposlinux.org,2015-10-28:jcantero/ld/2015/10/28/una-apuesta-por-las-licencias-copyleft/<p>En la última LinuxCon Europe Martin Fink dió una conferencia sobre el
estado actual de las licencias de software libre, e invitó al resto de
empresas a abrazar las ventajas de las licencias recíprocas o <em>copyleft</em>
(la familia GPL) frente a las permisivas (Apache, BSD, MIT, etc). He
aquí el vídeo, del que también tenéis un resumen por escrito en este
<a href="http://lwn.net/Articles/660428/">artículo de LWN.Net</a>:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/zxIEDNyZOkA" frameborder="0" allowfullscreen></iframe>
<p>No es muy habitual ver que desde la "industria" se apueste por las
licencias copyleft, así que cuando ocurre merece la pena reseñarlo.
Ojalá llegue un día en que esto esté tan asumido que no sea para nada
noticia.</p>
<p>:wq</p>
<p><a href="https://pumpit.info/jcantero/note/tIJLdUaMRfulZrUmPbqueA">Comentarios (a través de pump.io)</a></p>El nuevo X Server de Debian Stretch obliga a instalar systemd 2262015-10-19T16:26:00+02:00Javier Canterotag:www.escomposlinux.org,2015-10-19:jcantero/ld/2015/10/19/el-nuevo-x-server-de-debian-stretch-obliga-a-instalar-systemd-226/<p>Recientemente, uno de los mantenedores de las X en Debian <a href="https://www.reddit.com/r/debian/comments/3nz0vz/psa_x_server_is_now_running_as_regular_user/">contaba en
reddit/debian</a> que la nueva versión 1.17.2-3 iba a funcionar
sin permisos de root, siempre claro que tuvieras instalado
systemd-logind (y por lo tanto systemd) y usaras un driver gráfico con
KMS:</p>
<blockquote>
<p>This morning I've uploaded a new version (2:1.17.2-3) of the
xorg-server package into unstable.</p>
<p>With this version, the X server should run (in the majority of the
cases) under a regular user and not under root any more. If you want
this to work, you need to have logind running (and probably systemd as
PID1). The graphic driver should also support KMS.</p>
<p>If you are not using systemd or if your graphic driver (closed source
fglrx or nvidia driver) is not supporting KMS, you will need to install
the xserver-xorg-legacy package which now contains the setuid wrapper
used to run X as root (see Xorg.wrap(1) for more info)</p>
</blockquote>
<p>El segundo requerimiento deja fuera a los drivers binarios propietarios
de NVIDIA y AMD, que usan sus propios interfaces de <em>mode-setting</em><sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>
en vez del interfaz KMS estándar del kernel. Los usuarios de estos
drivers tendrán (tendremos) que seguir ejecutando las X como root, a
través de un <em>wrapper</em> que se instala mediante el nuevo paquete
<code>xserver-xorg-legacy</code>.</p>
<p>Hoy ese cambio ha llegado finalmente a Debian testing/Stretch, pero con
una desagradable sorpresa: los paquetes han quedado retenidos porque
rompen cualquier versión de systemd anterior a la 226-4:</p>
<div class="highlight"><pre>Package: xserver-xorg-core
Source: xorg-server
Version: 2:1.17.2-3
Architecture: amd64
Maintainer: Debian X Strike Force <debian-x@lists.debian.org>
Installed-Size: 5578
Depends: xserver-common (>= 2:1.17.2-3), keyboard-configuration, udev (>= 149), libegl1-mesa | libegl1, libaudit1 (>= 1:2.2.1), libc6 (>= 2.17), libdbus-1-3 (>= 1.9.14), libdrm2 (>= 2.3.1), libepoxy0 (>= 1.0), libgbm1 (>= 8.1~0), libgcrypt20 (>= 1.6.1), libgl1-mesa-glx | libgl1, libpciaccess0 (>= 0.12.902), libpixman-1-0 (>= 0.30.0), libselinux1 (>= 2.0.82), libudev1 (>= 183), libxau6, libxdmcp6, libxfont1 (>= 1:1.4.2), libxshmfence1
Recommends: libgl1-mesa-dri (>= 7.10.2-4)
Suggests: xfonts-100dpi | xfonts-75dpi, xfonts-scalable
Conflicts: xserver-xorg-input-evtouch, xserver-xorg-video-modesetting
Breaks: libgl1-mesa-dri (<< 7.10.2-4), libgl1-mesa-dri-experimental (<< 7.10.2-4), systemd (<< 226-4~), xserver-xorg (<< 1:7.7+10~), xserver-xorg-input, xserver-xorg-input-2, xserver-xorg-input-2.1, xserver-xorg-input-4, xserver-xorg-input-7, xserver-xorg-input-joystick (<= 1:1.5.0-3), xserver-xorg-input-synaptics (<= 1.2.2-1), xserver-xorg-input-tslib (<= 0.0.6-3), xserver-xorg-input-vmmouse (<= 1:12.6.5-4), xserver-xorg-input-wacom (<= 0.10.5+20100415-1), xserver-xorg-video, xserver-xorg-video-1.0, xserver-xorg-video-1.9, xserver-xorg-video-2, xserver-xorg-video-4, xserver-xorg-video-5, xserver-xorg-video-6, xserver-xorg-video-cyrix (<= 1:1.1.0-8), xserver-xorg-video-i810 (<< 2:2.4), xserver-xorg-video-imstt (<= 1:1.1.0-7), xserver-xorg-video-nsc (<= 1:2.8.3-4), xserver-xorg-video-sunbw2 (<= 1:1.1.0-5), xserver-xorg-video-v4l (<< 1:0.2.0), xserver-xorg-video-vga (<= 1:4.1.0-8)
Replaces: xserver-xorg (<< 1:7.7+10~), xserver-xorg-video-modesetting
Provides: xorg-input-abi-21, xorg-video-abi-19, xserver-xorg-video-modesetting
Section: x11
Priority: optional
</pre></div>
<p>Ese <em>Breaks:</em> en la práctica significa que, aunque no haya una
dependencia directa de systemd 226-4, sí que te obliga a usar <em>al menos</em>
esa versión de systemd si lo tienes instalado, lo que <a href="http://www.escomposlinux.org/jcantero/ld/2015/06/26/poniendole-la-correa-a-systemd-en-debian-stretch/">fastidia mi plan
de permanecer en systemd 215</a>.</p>
<p>Ahora mismo las X me están funcionando con las versiones anteriores de
los paquetes retenidos, pero tarde o temprano (y me temo que más
temprano que tarde) necesitaré actualizarlas por bugs de seguridad o
simplemente por otras dependencias, y con ellas la versión de systemd.
Tendré que pensar en otra solución, porque está claro que el truco de la
retención no va a durar mucho más. Y no va a ser nada nada fácil.</p>
<p><strong>Actualización:</strong> cambiado el título para que quede claro que estoy
hablando de Debian Stretch (aunque debería ser obvio)</p>
<p>:wq</p>
<p><a href="https://pumpit.info/jcantero/note/BhF3xP1uS5WY49w2yMf2NA">Comentarios (a través de pump.io)</a></p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>La buena noticia para los usuarios de tarjetas AMD de última
generación es que el nuevo driver oficial <code>amdgpu</code> sí va a ser KMS. <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>Pasa de Flash y ve videos nativamente con mpv (2): streams edition2015-10-17T17:47:00+02:00Javier Canterotag:www.escomposlinux.org,2015-10-17:jcantero/ld/2015/10/17/pasa-de-flash-y-ve-videos-nativamente-con-mpv-2-streams-edition/<p>En <a href="http://www.escomposlinux.org/jcantero/ld/2015/07/15/pasa-de-flash-y-ve-videos-nativamente-con-mpv/">"Pasa de Flash y ve videos nativamente con mpv"</a>
expliqué cómo ver videos de YouTube y sitios similares usando un
reproductor nativo en vez del pernicioso <em>plugin</em> de Flash, gracias a la
combinación de <a href="http://mpv.io/">mpv</a> y <a href="http://youtube-dl.org/">youtube-dl</a>. Esta vez usaremos otra
herramienta parecida a youtube-dl, pero orientada a sitios de
<em>streaming</em> como el popular Twitch: <a href="http://livestreamer.io/">livestreamer</a>. ¡Se os
están acabando las excusas!</p>
<p>Livestreamer es una utilidad de línea de comandos (<a href="https://github.com/chrippa/livestreamer">escrita en
Python</a>) que por defecto lanza <a href="http://www.videolan.org/">el reproductor VLC</a> para
ver el video del stream. Por suerte, también soporta mpv si se lo
indicamos con un parámetro:</p>
<div class="highlight"><pre>livestreamer http://twitch.tv/geekandsundry high --player mpv
</pre></div>
<p>Aquí estoy usando el <em>stream</em> <code>high</code> de entre los varios que oferta el
sitio (cada <em>stream</em> corresponde con un nivel de calidad y por lo tanto
de ancho de banda requerido). Para saber qué opciones tenemos para
elegir, simplemente indicamos la URL y livestreamer nos informa:</p>
<div class="highlight"><pre>$ livestreamer http://twitch.tv/geekandsundry
[cli][info] Found matching plugin twitch for URL http://twitch.tv/geekandsundry
Available streams: audio, high, low, medium, mobile (worst), source (best)
</pre></div>
<p>Para no tener que estar usando el parámetro <code>--player mpv</code> una y otra vez,
podemos indicar el reproductor a usar por defecto en el fichero de
configuración:</p>
<div class="highlight"><pre># Player options
player=mpv
</pre></div>
<p>Este fichero reside en <code>~/.livestreamerrc</code> o en
<code>.config/livestreamer/config</code> si se prefiere usar la <a href="http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html">especificación de
directorios de XDG</a><sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>.</p>
<p>Otra opción muy interesante es poder volcar el <em>stream</em> a un fichero
para poder verlo después con más calma si no nos es posible verlo en
directo:</p>
<div class="highlight"><pre>$ livestreamer http://twitch.tv/geekandsundry high -o grabacion
# [mucho tiempo despues]
^C
$ mpv grabacion
</pre></div>
<p>No olvidéis después borrar el fichero de grabación, porque dependiendo
de la calidad y el tiempo pueden ser ficheros de gigabytes.</p>
<p>En cuanto a la integración con Firefox (para los que no os guste la
línea de comandos), hay un <a href="https://addons.mozilla.org/en-US/firefox/addon/open-livestreamer/">plugin</a>, aunque yo no lo he
probado (también he visto que hay alguna UI <em>standalone</em>, pero parece
que es específica para Twitch).</p>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>siendo estrictos, el emplazamiento es <code>$XDG_CONFIG_HOME/livestreamer/config</code>. <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>Ultimas y próximas compilaciones del kernel2015-10-02T12:38:00+02:00Javier Canterotag:www.escomposlinux.org,2015-10-02:jcantero/ld/2015/10/02/ultimas-y-proximas-compilaciones-del-kernel/<p>Me he dado cuenta que los tiempos de compilación de los tres últimos
kernels de la serie 4.1 son más altos de lo que solían ser:</p>
<div class="highlight"><pre>$ time make -j4 deb-pkg LOCALVERSION=-amd64 KDEB_PKGVERSION=4.1.0-1
real 7m8.266s
user 21m37.484s
sys 1m5.384s
$ time make -j4 deb-pkg LOCALVERSION=-amd64 KDEB_PKGVERSION=4.1.1-1
real 7m3.663s
user 21m44.604s
sys 1m7.108s
$ time make -j4 deb-pkg LOCALVERSION=-amd64 KDEB_PKGVERSION=4.1.2-1
real 7m4.335s
user 21m35.884s
sys 1m6.444s
$ time make -j4 deb-pkg LOCALVERSION=-amd64 KDEB_PKGVERSION=4.1.3-1
real 7m4.535s
user 21m39.636s
sys 1m6.964s
$ time make -j4 deb-pkg LOCALVERSION=-amd64 KDEB_PKGVERSION=4.1.4-1
real 7m2.917s
user 21m34.572s
sys 1m6.288s
$ time make -j4 deb-pkg LOCALVERSION=-amd64 KDEB_PKGVERSION=4.1.5-1
real 7m4.600s
user 21m37.088s
sys 1m7.296s
$ time make -j4 deb-pkg LOCALVERSION=-amd64 KDEB_PKGVERSION=4.1.6-1
real 7m3.761s
user 21m42.748s
sys 1m8.192s
$ time make -j4 deb-pkg LOCALVERSION=-amd64 KDEB_PKGVERSION=4.1.7-1
real 7m21.898s
user 22m25.100s
sys 1m8.088s
$ time make -j4 deb-pkg LOCALVERSION=-amd64 KDEB_PKGVERSION=4.1.8-1
real 7m18.727s
user 22m20.260s
sys 1m6.676s
$ time make -j4 deb-pkg LOCALVERSION=-amd64 KDEB_PKGVERSION=4.1.9-1
real 7m24.771s
user 22m18.148s
sys 1m5.336s
</pre></div>
<p>Me estaba preguntando por qué, cuando me he acordado <a href="http://www.escomposlinux.org/jcantero/ld/2015/07/19/transicion-a-gcc5-en-debian/">del cambio de
versión del compilador</a>. Y resulta que encaja
perfectamente:</p>
<div class="highlight"><pre>Linux version 4.1.6-amd64 (gcc version 4.9.3 (Debian 4.9.3-3) ) #1 SMP
Linux version 4.1.7-amd64 (gcc version 5.2.1 20150903 (Debian 5.2.1-16) ) #1 SMP
Linux version 4.1.8-amd64 (javier@hogwarts) (gcc version 5.2.1 20150911 (Debian 5.2.1-17) ) #1 SMP
Linux version 4.1.9-amd64 (javier@hogwarts) (gcc version 5.2.1 20150911 (Debian 5.2.1-17) ) #1 SMP
</pre></div>
<p>El tiempo de compilación del kernel ha pasado de ~425 segundos con gcc
4.9 a ~440 segundos con el <em>shiny new compiler</em><sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup> gcc 5.2, es decir,
un incremento del 3,5%. Algunos considerarían esto una regresión...</p>
<p>¿Que por qué no estoy ya en la rama 4.2? Pues fundamentalmente <a href="https://forums.geforce.com/default/topic/849487/linux-v4-2-uses-gpl-only-symbol-flush_workqueue-/">por
culpa del driver propietario de NVIDIA</a> (¡qué
<a href="http://www.escomposlinux.org/jcantero/ld/2015/02/09/linux-319-y-algunos-bugs-en-318/">novedad</a>!). En el kernel 4.2 han refactorizado algo
que ha provocado que una función que antes tenía un <em>wrapper</em> ahora haya
quedado expuesta como símbolo GPL, o sea, de los que por
incompatibilidad de licencias el driver propietario de NVIDIA no puede
usar (al menos no directamente). En las <em>release candidates</em> de 4.3 ya
lo han <a href="https://git.kernel.org/cgit/linux/kernel/git/tj/wq.git/commit/?h=for-4.3&id=1dadafa86a779884f14a6e7a3ddde1a57b0a0a65">"arreglado"</a>, pero el mismo parche no ha sido
incorporado a la rama estable <a href="https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/commit/?id=4f7760e963db10618dd3617bcf6254d896094e37">hasta la versión 4.2.2</a>.</p>
<p>Y ya que estamos hablando de compilaciones de kernels, aprovecho para
avisar de <a href="http://www.spinics.net/lists/linux-kbuild/msg11616.html">un cambio</a> en los <em>scripts</em> de KBuild de los
kernels 4.3 que afecta a cómo se generan los paquetes <code>.deb</code>:</p>
<blockquote>
<p>make deb-pkg generates a source package, bindeb-pkg has been added
to only generate the binary package</p>
</blockquote>
<p>O sea, que a partir de los kernels 4.3 <code>make dpkg-deb</code> construye también
los paquete <em>source</em> (<code>*.orig.tar.gz</code>, <code>*.debian.tar.gz</code> y <code>*.dsc</code>) con
los fuentes del kernel. Los que no queramos perder el tiempo
generándolos —la mayoría— tendremos que usar en su lugar el nuevo
<em>target</em> <code>make bindeb-pkg</code>.</p>
<p>Me he enterado del cambio porque llevo un tiempo echando un vistazo
(muy) de vez en cuando a la lista <a href="http://www.spinics.net/lists/linux-kbuild/">linux-kbuild</a> y a la
<a href="https://github.com/torvalds/linux/commits/master/scripts/package/builddeb">historia del fichero <code>scripts/package/builddeb</code></a>. La
razón es que estoy interesado en que incorporen <a href="https://lists.debian.org/debian-kernel/2015/04/msg00013.html">este
parche</a> que añade el paquete <code>linux-tools-*.deb</code> (donde
reside <code>perf</code>) a los que se generan actualmente. Pero no parece que haya
mucha prisa, ya que es la tercera <em>merge window</em> que se queda fuera. Tal
vez haya que mostrar algo de interés desde fuera, a ver si se animan.
<code>O:-)</code></p>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>Linus <a href="http://lkml.iu.edu//hypermail/linux/kernel/1407.3/00650.html"><em>dixit</em></a> <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>Más recetas de privacidad para Firefox (e Iceweasel)2015-09-23T12:45:00+02:00Javier Canterotag:www.escomposlinux.org,2015-09-23:jcantero/ld/2015/09/23/mas-recetas-de-privacidad-para-firefox-e-iceweasel/<p>La gente de Mozilla se empeña en meternos por el gaznate más
"características" que atentan contra nuestra privacidad. Así que, de vez
en cuando nos va a tocar ampliar más y más la <a href="http://www.escomposlinux.org/jcantero/ld/2015/06/27/aun-mas-privacidad-para-firefox-e-iceweasel/">lista de opciones a
retocar en el <code>about:config</code></a>.</p>
<p>La nueva fuga de privacidad viene por los "sitios sugeridos": no basta
con evitar que el navegador muestre estos sitios (que en realidad no son
más que una forma encubierta de colocarnos publicidad) haciendo que la
nuevas pestañas abran una página en blanco (ver la <strong>Actualización</strong>).
También hay que evitar activamente que el sistema recopile información
sobre nosotros y la envíe a los cuarteles centrales de Mozilla.</p>
<p>Porque eso es exactamente lo que hace <a href="https://support.mozilla.org/en-US/kb/about-tiles-new-tab">esta característica</a>:
recopilar información sobre cuántas veces se muestra cada miniatura de
sitio y en qué posición, la interacción con cada miniatura (si se pulsa,
si se cambia de lugar, si se pasa por encima de ella, etc). E incluso el
idioma configurado. Y toda esta información se envía a los servidores de
Mozilla, supuestamente para "poder sugerirnos otros sitios que nos
pueden interesar" (sic).<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup></p>
<p>Las alegaciones de que en realidad no se guarda la IP, y que los datos
sólo se almacenan durante 7 días no hacen menor la violación de
privacidad a pesar de lo que Mozilla pretende haceros creer (y eso
suponiendo que fueran totalmente honestos). Veámoslo de esta otra forma:
a Mozilla le da igual quién seas mientras sea capaz de colocarte la
publicidad más adecuada a tu perfil. ¿Véis el contrasentido?</p>
<p>Pero vayamos al grano. Las opciones de <code>about:config</code> relacionadas con
esta basura son las que comienzan por "browser.newtabpage":</p>
<div class="highlight"><pre>browser.newtabpage.directory.ping localhost
browser.newtabpage.directory.source localhost
browser.newtabpage.enabled false
browser.newtabpage.enhanced false
</pre></div>
<p>Prefiero poner "localhost" en vez de dejar el campo vacío en los valores
que son URLs por si existe algún valor por defecto de <em>fallback</em> si el
éste no es interpretable.</p>
<p>Ya que me aparecían en la misma búsqueda, he cambiado estos otros
valores a <code>false</code>. En teoría todo lo del Firefox Sync lo tengo
desactivado, pero por si acaso:</p>
<div class="highlight"><pre>services.sync.prefs.sync.browser.newtabpage.enabled false
services.sync.prefs.sync.browser.newtabpage.enhanced false
services.sync.prefs.sync.browser.newtabpage.pinned false
</pre></div>
<p>De todas formas, no es sostenible que cada usuario tenga que estar
revisando una y otra vez las configuraciones por si le han colado otro
"gol". Ya hay voces por ejemplo entre los usuarios de Debian que
reclaman que los mantenedores suministren si no un Iceweasel modificado,
al menos una versión con una configuración por defecto "reforzada" en
cuanto a la privacidad (que todas estas opciones vengan ya con valores
por defecto recomendables). Mientras no se haga nada así, tendremos que
seguir tirando de consejos de aquí y de allá (no todos ellos acertados o
fiables), lo cual no es una buena situación y además de deja al resto de
usuarios que no conocen estos temas totalmente desprotegidos.</p>
<p><strong>BONUS</strong>: Otra recopilación: <a href="https://gist.github.com/haasn/69e19fc2fe0e25f3cff5">Firefox bullshit removal</a></p>
<p><strong>Actualización:</strong> resulta que la opción <code>browser.newtab.url</code>
desaparece del <code>about:config</code> a partir de Firefox 41, y sólo se podrá
cambiar la dirección de apertura de una nueva pestaña <a href="https://addons.mozilla.org/en-us/firefox/addon/new-tab-override/">a través de un
<em>add-on</em></a>. Más razón si cabe para hacer los cambios
sugeridos arriba.</p>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>y yo voy y me lo creo. <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>El bug de aptitude que olvida los indicadores Auto2015-09-19T10:49:00+02:00Javier Canterotag:www.escomposlinux.org,2015-09-19:jcantero/ld/2015/09/19/el-bug-de-aptitude-que-olvida-los-indicadores-auto/<p>Cuando aptitude o apt instalan un paquete, guardan cierta información
conocida como indicador Auto sobre si el paquete fue instalado a
petición del usuario (Manual) o porque era necesario para resolver una
dependencia (Automático). La herramienta de gestión de paquetes puede
decidir posteriormente si puede desinstalar paquetes que ya no son
necesarios basándose en este indicador, y de esta forma mantener las
dependencias del sistema al mínimo imprescindible, con las ventajas que
ello conlleva<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>.</p>
<p>Por desgracia, la implementación de esta funcionalidad tanto en aptitude
como en apt ha sido históricamente defectuosa, y de vez en cuando
algunas operaciones provocan que el indicador Auto de algunos paquetes
se "olvide". Podéis encontrar múltiples informes de error en el <em>Bug
Tracking System</em> de Debian referidos a esta situación, como los
<a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=490547">#490547</a> y <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=638049">#638049</a> de aptitude, y <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=638049#10">hay
más</a> (a los que habría que sumar los reportados contra
apt).</p>
<p>Cuando escribí <a href="http://www.escomposlinux.org/jcantero/ld/2015/05/20/radiografia-de-paquetes-instalados-en-debian/">Radiografía de paquetes instalados en
Debian</a>, di por hecho que estos bugs habían sido
arreglados definitivamente. Fundamentalmente porque, en los meses que
transcurrieron entre que apliqué las técnicas que se describen ahí para
encontrar y recuperar los indicadores Auto y la publicación del
artículo, no había sufrido ningún otro caso de indicador perdido<sup id="fnref:2"><a class="footnote-ref" href="#fn:2" rel="footnote">2</a></sup>. No
ha sido hasta recientemente que, haciendo una comprobación rutinaria de
bibliotecas no instaladas automáticamente, me he encontrado que
nuevamente tenía paquetes sin el indicador Auto que deberían haberlo
tenido. Desde entonces estoy realizando chequeos periódicos, tanto de
paquetes de bibliotecas como del resto de paquetes, lo que me ha
aportado valiosa información acerca de la naturaleza del bug, como
explicaré más adelante.</p>
<p>El caso es que el bug difícilmente podía haber sido arreglado: resulta
que aptitude ha estado desde 2011 sin un mantenedor activo la mayor
parte del tiempo. Si queréis saber toda la —lamentable— historia, leed
la resolución del Comité Técnico en <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=750135">#750135 Determine maintainer of
aptitude package</a>. La situación finalmente se ha desbloqueado
el pasado mes de Agosto, y ahora el repositorio de aptitude vuelve a
tener vida. Pero eso no significa necesariamente que alguien vaya a
trabajar activamente en arreglar esos bugs, en todo caso que si alguien
consigue algo, su trabajo puede ser ahora incorporado a <em>upstream</em> en
vez de languidecer en el BTS.</p>
<p>Uno de los puntos fundamentales a la hora de encontrar la causa de un
bug o error es ser capaz de reproducirlo. Si se consigue, se tiene la
mitad del camino recorrido para resolverlo<sup id="fnref:3"><a class="footnote-ref" href="#fn:3" rel="footnote">3</a></sup>. En este caso era
importante saber si el bug se producía "de forma aleatoria" o estaba
ligado a ciertas situaciones. Lo primero hubiera significado algún tipo
de condición de carrera, y esos errores son difíciles de encontrar y
solucionar. Pero si es un error que se puede reproducir una y otra vez,
los programadores tienen una buena oportunidad de pillarlo "in
fraganti". En mi caso el darme cuenta del bug casi de inmediato, cuando
todavía me acordaba con detalle qué había pasado anteriormente, y el
hecho de poder reproducirlo fácilmente me ha permitido deducir que
estaba ante un bug del segundo tipo, por lo que tenía una buena
oportunidad de cazarlo. Era cuestión de analizar detenidamente la
situación (los paquetes y sus dependencias antes y después de la
actualización) y ver si ello me permitía descubrir la combinación de
factores que desencadenaban el bug.</p>
<p>Voy a explicar la situación exacta para que sigáis conmigo mis
razonamientos: la anterior actualización había introducido un nuevo
paquete llamado <code>pelican</code><sup id="fnref:4"><a class="footnote-ref" href="#fn:4" rel="footnote">4</a></sup>. Este paquete no era más que una
actualización del paquete <code>python-pelican</code>, pero con el nombre
cambiado<sup id="fnref:5"><a class="footnote-ref" href="#fn:5" rel="footnote">5</a></sup>. Además le acompañaba una nueva versión del paquete
<code>python-pelican</code> pero sin contenido (lo que se llama un paquete
<em>transicional</em>) con una dependía de <code>pelican</code>. Hasta aquí todo normal,
es lo que <a href="https://wiki.debian.org/Renaming_a_Package">se hace cuando se quiere cambiar el nombre a un
paquete</a>: introducir uno con el nombre nuevo y descontinuar
el paquete con el nombre antiguo. Como parte de este cambio, el paquete
nuevo "hereda" las dependencias del antiguo, mientras que el antiguo se
queda sin dependencias (al estar vacío), excepto una al paquete nuevo
(para forzar al gestor de paquetes a instalar el nuevo paquete si se
tenía instalado el antiguo).</p>
<p>En ese momento no le di más importancia al cambio. Fue mucho más tarde,
cuando me puse a revisar la lista de paquetes instalados manualmente<sup id="fnref:6"><a class="footnote-ref" href="#fn:6" rel="footnote">6</a></sup>
y a compararla con la última versión que tenía de la misma, cuando me
encontré con todos estos paquetes "nuevos" sin el indicador de Auto:</p>
<div class="highlight"><pre>i docutils-common 0.12+dfsg-1 - text processing system for reStruc
i pelican 3.6.0-4 - blog aware, static website generat
i python-pelican 3.6.0-1 - blog aware, static website generat
i python-blinker 1.3.dfsg2-1 - Fast, simple object-to-object and
i python-dateutil 2.2-2 - powerful extensions to the standar
i python-docutils 0.12+dfsg-1 - text processing system for reStruc
i python-feedgenerator 1.7-2 - Syndication feed generation librar
i python-jinja2 2.7.3-1 - small but fast and easy to use sta
i python-markdown 2.6.2-1 - text-to-HTML conversion library/to
i python-markupsafe 0.23-2 - HTML/XHTML/XML string library for
i python-pygments 2.0.1+dfsg-1.1 - syntax highlighting package writte
i python-roman 2.0.0-1 - module for generating/analyzing Ro
i python-unidecode 0.04.16-1 - ASCII transliterations of Unicode
</pre></div>
<p>Cuando me puse a investigar de dónde habían salido esos paquetes
(excepto <code>python-pelican</code> que había instalado yo a mano) es cuando me dí
cuenta que todos eran dependencias de <code>pelican</code> —y anteriormente de
<code>python-pelican</code>—. ¿Justo hay un cambio de paquete <code>python-pelican</code> a
<code>pelican</code> y sus dependencias pierden el indicador Auto? Sospechoso.</p>
<p>Para verificar que efectivamente el bug podía estar relacionado con la
"migración de dependencias" entre paquetes, lo primero que hice fue
reproducir de nuevo la situación de partida, instalando el anterior
<code>python-pelican</code> 3.5.0-1, desinstalando <code>pelican</code> y reseteando los
indicadores de estos paquetes nuevamente a Auto. Tras hacer de nuevo el
<code>aptitude upgrade</code> los mismos paquetes volvieron a perder el indicador.</p>
<p>Una vez tenía la confirmación fehaciente de que era un bug reproducible
y no aleatorio, era el momento de ponerse a investigar más a fondo. Por
no alargarme demasiado, resumiré gráficamente la situación con un
diagrama de dependencias del paquete <code>pelican</code> (el mismo que utilicé en
ese momento):</p>
<p><img alt="Diagrama de dependencias de pelican" src="http://www.escomposlinux.org/jcantero/ld/images/aptitude-bug-1.png" /></p>
<p>(Había más dependencias hacia la derecha pero las he descartado porque
no aportan nada relevante a la discusión)</p>
<p>Como podéis comprobar vosotros mismos cotejando la lista anterior de
paquetes y la gráfica, habían perdido el indicador Auto las dependencias
de <code>pelican</code>, así como las dependencias de estas dependencias. Sin
embargo, había algunas excepciones: <code>python-pkg-resources</code>, <code>python-six</code>
y <code>python-tz</code>, a pesar de ser dependencias directas de <code>pelican</code>,
conservaban aún el Auto. La pregunta era por qué, y si había alguna
diferencia que lo justificara.</p>
<p>Analizando las dependencias inversas de todos estos paquetes encontré
que mientras los paquetes que no tenían otras dependencias inversas que
<code>pelican</code> habían perdido su indicador, los que tenían otras dependencias
inversas lo conservaban. Este diagrama ampliado aclara lo que quiero
decir:</p>
<p><img alt="Diagrama de dependencias de pelican ampliado" src="http://www.escomposlinux.org/jcantero/ld/images/aptitude-bug-2.png" /></p>
<p>Este diagrama muestra que otros paquetes aparte de <code>pelican</code> dependen de
<code>python-pkg-resources</code>, y lo mismo pasa con <code>python-six</code>, del que
también dependen <code>python-cryptography</code>, <code>python-openssl</code> y
<code>python-debian</code> además de <code>python-dateutil</code> y <code>python-feedgenerator</code>.
El tercer caso, <code>python-tz</code>, es el más problemático, ya que no recibe
dependencias de otros paquetes externos, sólo de <code>pelican</code> y
<code>python-feedgenerator</code>. Pero curiosamente es el único<sup id="fnref:7"><a class="footnote-ref" href="#fn:7" rel="footnote">7</a></sup> que tiene a
la vez una dependencia directa y una indirecta (a través de
<code>python-feedgenerator</code>) de <code>pelican</code>.</p>
<p>Por otro lado tenemos paquetes como <code>docutils-common</code>,
<code>python-markupsafe</code> y <code>python-roman</code>, que no son dependencias directas
de <code>pelican</code> (aunque sí indirectas, a través de <code>python-jinja2</code> y
<code>python-docutils</code>) pero que aún así pierden el indicador. Los tres son
dependencias de paquetes —y sólo de estos paquetes— que pierden el
indicador Auto, lo que sugiere algún tipo de comportamiento recursivo.</p>
<p>La hipótesis que se estaba formando en mi mente era que al "migrar" las
dependencias de un paquete <code>A</code> a otro distinto <code>A'</code> (que en el caso
anterior corresponderían a <code>python-pelican</code> y <code>pelican</code>), los paquetes
de dichas dependencias —pongamos <code>B</code>, <code>C</code> y <code>D</code>— perdían en el proceso
el indicador Auto. En los casos en los que había un tercer paquete <code>Z</code>
implicado que también dependía de uno de dichos paquetes —pongamos <code>D</code>—
ésta otra dependencia de <code>Z</code> evitaba que <code>D</code> perdiera el Auto. Y además,
parecía un comportamiento recursivo: los paquetes que perdían el Auto
hacían que a su vez sus dependencias —<code>E</code>, <code>F</code>, <code>G</code> y <code>J</code>— lo perdieran
si éstas no tenían una dependencia inversa de otro paquete que lo
impidiera (como la de <code>Z</code> en el caso de <code>D</code>).</p>
<p>O sea, si la situación antes de un upgrade era esta (fondo gris para los
paquetes con el indicador Auto):</p>
<p><img alt="Ejemplo: antes del upgrade" src="http://www.escomposlinux.org/jcantero/ld/images/aptitude-bug-3.png" /></p>
<p>tras el upgrade que "migra" las dependencias de <code>A</code> a <code>A'</code> los paquetes
<code>B</code>, <code>C</code>, <code>E</code>, <code>F</code>, <code>G</code> y <code>J</code> habrían perdido el indicador Auto, pero no
el paquete <code>D</code>:</p>
<p><img alt="Ejemplo: despues del upgrade" src="http://www.escomposlinux.org/jcantero/ld/images/aptitude-bug-4.png" /></p>
<p>El siguiente caso que me permitió poner a prueba esta hipótesis fue
cuando entraron en el repositorio de <em>testing</em>/stretch <a href="http://www.escomposlinux.org/jcantero/ld/2015/07/21/llega-ffmpeg-a-stretch/">los paquetes de
ffmpeg que sustituían a los de libav</a>:</p>
<div class="highlight"><pre>Se instalarán los siguiente paquetes NUEVOS:
libavdevice-ffmpeg56{a} libavfilter-ffmpeg5{a} libpgm-5.1-0{a} libpostproc-ffmpeg53{a} libsodium13{a} libswscale-ffmpeg3{a} libzmq3{a}
Se ELIMINARÁN los siguientes paquetes:
libavdevice55{u} libavfilter5{u} libpostproc52{u} libswscale3{u}
Se actualizarán los siguientes paquetes:
mplayer2 mpv
</pre></div>
<p>Aquí tenemos un nuevo caso del patrón "renombramiento de paquetes" (esta
vez añadiendo el sufijo <code>--ffmpeg</code>) donde los nuevos paquetes reciben
las dependencias que pierden los antiguos. Tras esa actualización, 3
paquetes de bibliotecas dinámicas perdieron el indicador Auto:</p>
<div class="highlight"><pre>i libopencv-core2.4 2.4.9.1+dfsg-1 - computer vision core library
i libopencv-imgproc2.4 2.4.9.1+dfsg-1 - computer vision Image Processing l
i libtbb2 4.2~20140122-5 - parallelism library for C++ - runt
</pre></div>
<p>Y aquí el diagrama con las dependencias implicadas:</p>
<p><img alt="Diagrama de dependencias de ffmpeg" src="http://www.escomposlinux.org/jcantero/ld/images/aptitude-bug-5.png" /></p>
<p>Lo particular de este caso es que es más explícito el comportamiento
recursivo de la pérdida del indicador Auto. No sólo afecta a 3 niveles
de profundidad en vez de 2 del caso anterior, sino que además es una
cadena muy clara y sin interferencias de otros paquetes.</p>
<h1>Afinando la puntería</h1>
<p>A estas alturas creo que ya os habré convencido sobre la sintomatología
del bug<sup id="fnref:8"><a class="footnote-ref" href="#fn:8" rel="footnote">8</a></sup>, pero queda por averiguar cuál es su causa (si es que
queremos resolverlo). Es obvio que algo no está funcionando
correctamente en aptitude, pero aptitude son <a href="http://sources.debian.net/src/aptitude/0.6.11-1/">más de 90.000 líneas de
código C++</a>, y una pista con la que poder acotar la
búsqueda sería muy de agradecer.</p>
<p>Y es posible que la haya encontrado. Mirando bugs aquí y allá en el BTS
he visto el siguiente <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=622719#15">comentario</a> del propio autor de
aptitude Daniel Burrows:</p>
<blockquote>
<p>This changed in revision 2085.1.1 of apt. <rant>Fer crying out loud,
if I had the time I'd just ditch their handling of the auto flag and do
it myself</rant>. What's especially frustrating is that they tried to
accommodate aptitude, but they didn't understand what they were doing.
Guess it's really my fault for not keeping up on this stuff.</p>
<p>I guess that as a workaround (ew) I can save the auto flag before I
call MarkInstall and restore it afterwards.</p>
</blockquote>
<p>¿No os da la impresión como a mí de estar contemplando el origen del
bug? Me refiero al segundo párrafo. Si lo que hace aptitude actualmente
es guardar los indicadores Auto antes de empezar el upgrade y
restaurarlos después, al actualizarse el paquete antiguo y quedarse sin
las dependencias durante el upgrade, es muy posible que la herramienta
pierda debido a ello el rastro de los indicadores Auto de esos paquetes
y luego no pueda restaurarlos simplemente porque carece de la
información. Cuando hay otros paquetes implicados, la dependencia que
permanece "fija" permite que aptitude conserve la información del
indicador Auto y pueda restaurarlo al final. Si este proceso es además
recursivo, lo cual es una buena suposición<sup id="fnref:9"><a class="footnote-ref" href="#fn:9" rel="footnote">9</a></sup>, la hipótesis encajaría
perfectamente.</p>
<p>De todas formas, antes de meterme a revisar código creo que lo primero
es construir un "test sintético", un ejemplo ficticio de repositorio de
paquetes con dependencias (similar al caso <code>A</code>, <code>B</code>, <code>C</code>, ... de arriba)
que sirva para probar las veces que haga falta la situación en la que
ocurre el bug. A partir de ahí se puede enviar un informe de error a los
mantenedores actuales de aptitude, proporcionándoles de paso una forma
sencilla de reproducir el bug ellos mismos. Y si tras ello no se les ve
interesados, entonces se puede empezar a pensar en meterse a bucear en
el código fuente de aptitude.</p>
<p>En cualquier caso seguiré informando.</p>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>el espacio en disco hoy en día se considera "barato", pero
más software instalado implica también más bugs, incluyendo más
bugs de seguridad. <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>probablemente porque ese periodo coincidió en su mayoría con el
<em>freeze</em> de Jessie, durante el cual las dependencias entre
paquetes cambiaron poco o nada. <a class="footnote-backref" href="#fnref:2" rev="footnote" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:3">
<p>aunque muchas veces la otra mitad del camino puede terminar
suponiendo el 80% del trabajo. <a class="footnote-backref" href="#fnref:3" rev="footnote" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
<li id="fn:4">
<p>que curiosamente es el paquete del <em>static site generator</em> con
el que genero este blog. <a class="footnote-backref" href="#fnref:4" rev="footnote" title="Jump back to footnote 4 in the text">↩</a></p>
</li>
<li id="fn:5">
<p>ignoro la razón concreta para querer cambiar el nombre de este
paquete, pero Debian no debería permitir renombrar paquetes a la
ligera. <a class="footnote-backref" href="#fnref:5" rev="footnote" title="Jump back to footnote 5 in the text">↩</a></p>
</li>
<li id="fn:6">
<p>con el comando que detallo en el ya mencionado artículo de
<a href="http://www.escomposlinux.org/jcantero/ld/2015/05/20/radiografia-de-paquetes-instalados-en-debian/">Radiografía de paquetes instalados en Debian</a>. <a class="footnote-backref" href="#fnref:6" rev="footnote" title="Jump back to footnote 6 in the text">↩</a></p>
</li>
<li id="fn:7">
<p>siendo estrictos no es el único, <code>python-six</code> también tiene
una dependencia directa y una indirecta, pero en este caso eso
no invalida el razonamiento si no que lo refuerza. <a class="footnote-backref" href="#fnref:7" rev="footnote" title="Jump back to footnote 7 in the text">↩</a></p>
</li>
<li id="fn:8">
<p>al menos de <em>este</em> bug, puede haber otros que se produzcan bajo
otras circunstancias similares pero independientes. <a class="footnote-backref" href="#fnref:8" rev="footnote" title="Jump back to footnote 8 in the text">↩</a></p>
</li>
<li id="fn:9">
<p>la recursión es bastante común en algoritmos aplicados a árboles
y grafos. <a class="footnote-backref" href="#fnref:9" rev="footnote" title="Jump back to footnote 9 in the text">↩</a></p>
</li>
</ol>
</div>La transición a GCC5 llega a Debian Testing2015-09-06T18:43:00+02:00Javier Canterotag:www.escomposlinux.org,2015-09-06:jcantero/ld/2015/09/06/la-transicion-a-gcc5-llega-a-debian-testing/<p>Tras <a href="http://www.escomposlinux.org/jcantero/ld/2015/07/19/transicion-a-gcc5-en-debian/">casi dos meses cocinándose en <em>unstable</em></a> la temida
transición a GCC5 y la nueva libstdc++6 <a href="https://lists.debian.org/debian-devel/2015/09/msg00146.html">ha llegado a Debian Testing
(Stretch)</a>:</p>
<blockquote>
<p>we are ready to migrate the bulk of the GCC-5 transition and related
sub-transitions to testing tonight. Apologise for the short notice.</p>
<p>We expect this to be <em>mostly</em> a smooth ride, but there are some
caveats:</p>
<ul>
<li>
<p>We will have to remove some packages from testing temporarily</p>
</li>
<li>
<p>A total of 36 (amd64) / 31 (i386) binary packages will become
uninstallable in testing.</p>
</li>
</ul>
</blockquote>
<p>La actualización me ha resultado poco problemática, gracias a que he
seguido unas cuantas buenas prácticas:</p>
<ul>
<li>
<p>Los paquetes que han quedado temporalmente obsoletos en <em>testing</em> lo
son por buenos motivos (dependencias que no se van a poder cumplir
tras la transición) y por lo tanto lo mejor es desinstalarlos hasta
que vuelvan a reintroducirse en el archivo (ya con dependencias
actualizadas). Dejarlos instalados sólo va a llevar a conflictos
irresolubles por el <em>package resolver</em>.</p>
</li>
<li>
<p>Evitar utilizar <em>sources</em> que no sean las oficiales de Debian (los
mantenedores que hacen la transición no los tienen en cuenta).</p>
</li>
<li>
<p>Otra cosa que se le atraganta al <em>package resolver</em> son los paquetes
que pierden su indicador de "instalado automáticamente", ya que el
<em>resolver</em> en modo <em>upgrade</em> (<em>safe-upgrade</em>) no toca los paquetes
que el usuario ha instalado manualmente. Estos paquetes, que por
dependencias deberían haberse borrado no lo hacen, y eso provoca que
<em>upgrade</em> simplemente los retenga. Los usuarios pueden intentar
forzar la situación con un <em>dist-upgrade</em> (<em>full-upgrade</em>), y es
entonces cuando el <em>resolver</em> se ve obligado a preguntar al usuario
sobre qué paquetes eliminar y cuáles mantener. Lo mejor para evitarlo
es <a href="http://www.escomposlinux.org/jcantero/ld/2015/05/20/radiografia-de-paquetes-instalados-en-debian/">mantener los paquetes con sus indicadores correctos de "instalado
automáticamente"</a>.</p>
</li>
</ul>
<p>Este problema se ve acentuado porque los mantenedores han decidido que,
en vez de actualizar directamente el paquete, existan 2 versiones de
ciertos paquetes (fundamentalmente de bibliotecas escritas en C++): la
antigua y la nueva, que es la versión compilada con GCC5 y contra la
nueva libstdc++6. El paquete con la versión antigua conserva el nombre
mientras que el de la nueva se le añade al nombre un sufijo "v5". De
esta forma, la transición de ciertos paquetes puede hacerse
independiente de la de otros, y se evita tener que hacer la transición
de todo a la vez.</p>
<p>El problema de este enfoque es que ciertos bugs en aptitude/libapt-pkg
que hacen que se pierda el indicador de "instalado automáticamente"
se disparan cuando se hace este tipo de transiciones de cambios de
nombres<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>. En mi caso, tras hacer el <code>aptitude upgrade</code> 20 bibliotecas
y otros 7 paquetes perdieron el indicador. Tuve que hacer un
<code>markauto</code> de todos ellos para poder seguir.</p>
<p>Una cosa que hice es seguir el principio <em>divide et impera</em>. Sabiendo
que el paquete más problemático probablemente iba a ser libstdc++6, lo
primero que hice fue asegurarme que se actualizaba con un <code>aptitude
install libstdc++6</code>. Después, volví a revisar si más paquetes habían
perdido el indicador "Auto" y a volvérselo a poner. Y finalmente, un
nuevo <code>aptitude upgrade</code> me hizo la actualización de la mayoría de los
paquetes que faltaban. Unos detalles más, y actualmente sólo tengo
retenidos 10 paquetes por dependencias no resolubles, que espero que en
los próximos días se solucionen.</p>
<p>Seguiré informando.</p>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>Este bug espero desarrollarlo más ampliamente en un próximo
artículo. <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>Nueva política de menus en Debian2015-09-04T18:29:00+02:00Javier Canterotag:www.escomposlinux.org,2015-09-04:jcantero/ld/2015/09/04/nueva-politica-de-menus-en-debian/<p>El Comité Técnico de Debian <a href="https://lists.debian.org/debian-devel-announce/2015/09/msg00000.html">ha decidido</a> a favor de
sustituir el viejo <a href="https://www.debian.org/doc/packaging-manuals/menu.html/">sistema de menus de Debian</a> por <a href="http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-latest.html">la
especificación estándar de menus de FreeDesktop</a>, que es la que
siguen escritorios como KDE, GNOME o Xfce, y la que en la actualidad
usan la mayoría de las distribuciones modernas.</p>
<blockquote>
<p>The Technical Committee has reviewed the underlying technical
issues around this question and has resolved that Debian will be
best served by migrating away from our own Debian Menu System and
towards the common Freedesktop Desktop Entry Specification, and
that menu information for applications should not be duplicated in
two different formats.</p>
</blockquote>
<p>Debido a la obsolescencia del sistema de menus de Debian, a la
omnipresencia de la especificación de XDG y al esfuerzo que supone
mantener ambos formatos (sobre todo mantener los datos sincronizados)
esto era algo que iba a pasar tarde o temprano. Sólo los usuarios que
utilizan <em>window managers</em> en vez de escritorios se beneficiaban del
antiguo sistema de menus, aunque cada vez con un soporte más deficiente
(por ejemplo cada vez es más difícil encontrar aplicaciones que
distribuyan su icono en formato <code>.xpm</code>).</p>
<p>Escribir un lanzador para tu aplicación es bastante sencillo con la
especificación de FreeDesktop, basta con crear un fichero con extensión
<code>.desktop</code> en <code>.local/share/applications/</code> o, en caso que queramos que
sea global a todos los usuarios, en <code>/usr/share/applications/</code> y
rellenar sus campos:</p>
<div class="highlight"><pre><span class="k">[Desktop Entry]</span>
<span class="na">Version</span><span class="o">=</span><span class="s">1.0</span>
<span class="na">Name</span><span class="o">=</span><span class="s">Aplicacion</span>
<span class="na">Comment</span><span class="o">=</span><span class="s">Este es un ejemplo de lanzador de Aplicación</span>
<span class="na">TryExec</span><span class="o">=</span><span class="s">/ruta/a/ejecutable</span>
<span class="na">Exec</span><span class="o">=</span><span class="s">/ruta/a/ejecutable</span>
<span class="na">Icon</span><span class="o">=</span><span class="s">/ruta/a/icono</span>
<span class="na">Path</span><span class="o">=</span><span class="s">/ruta/a/directorio/aplicacion</span>
<span class="na">Terminal</span><span class="o">=</span><span class="s">false</span>
<span class="na">Type</span><span class="o">=</span><span class="s">Application</span>
<span class="na">Categories</span><span class="o">=</span><span class="s">Utility;</span>
</pre></div>
<p>Hay muchos más campos útiles para rellenar, y el formato también soporta
internacionalización (múltiples idiomas), pero este ejemplo simple nos
sirve para hacernos una idea de cómo crear uno.</p>
<p>:wq</p>qpdfview2015-09-02T19:51:00+02:00Javier Canterotag:www.escomposlinux.org,2015-09-02:jcantero/ld/2015/09/02/qpdfview/<p>He estado evaluando varias alternativas <a href="http://www.escomposlinux.org/jcantero/ld/2015/06/30/desaparece-evince-gtk-de-debian-stretch/">para sustituir
evince-gtk</a>. Al principio había pensado compilarme yo
mismo una versión ligera (en el AUR existe <a href="https://aur.archlinux.org/packages/evince-light/">evince-light</a>),
pero tras leer los mensajes del <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=755071">bug #755071</a> (que es dónde
se decide el abandono de evince-gtk) me he dado cuenta que las
diferencias actuales entre evince y evince-gtk eran mínimas, y que el
problema del "aspecto GNOME3" de la aplicación no se iba a resolver así.
Otra posibilidad era usar <a href="https://github.com/mate-desktop/atril">atril</a>, que es el <em>fork</em> de evince que
han hecho la gente del escritorio MATE, pero éste a su vez trae un
montón de dependencias de éste escritorio, y me temo que encima es tan
ineficiente como el propio evince.</p>
<p>Al final, me he terminado decidiendo por <a href="https://launchpad.net/qpdfview">qpdfview</a>:</p>
<div class="highlight"><pre># aptitude install qpdfview
Se instalarán los siguiente paquetes NUEVOS:
libpoppler-qt5-1{a} libqt5concurrent5{a} libqt5core5a{a} libqt5dbus5{a} libqt5gui5{a} libqt5printsupport5{a} libqt5sql5{a} libqt5sql5-sqlite{a}
libqt5svg5{a} libqt5widgets5{a} libqt5xml5{a} libxcb-icccm4{a} libxcb-image0{a} libxcb-keysyms1{a} libxcb-render-util0{a} libxcb-xkb1{a}
libxkbcommon-x11-0{a} qpdfview
Se RECOMIENDAN los siguientes paquetes, pero NO se instalarán:
qpdfview-djvu-plugin qpdfview-ps-plugin qpdfview-translations qttranslations5-l10n
0 paquetes actualizados, 18 nuevos instalados, 0 para eliminar y 8 sin actualizar.
Necesito descargar 0 B/7.780 kB de ficheros. Después de desempaquetar se usarán 26,4 MB.
</pre></div>
<p>Se podría pensar que, como es una aplicación Qt5, sería bastante pesada,
pero evince ocupa casi el doble de memoria virtual (lo cual es bastante
ridículo), y no va ni mucho menos tan fluido. Además, abriendo el mismo
documento PDF con ambas aplicaciones, lado por lado, tengo la impresión
(subjetiva) que qpdfview renderiza algo mejor, a pesar de estar ambas
basadas en <a href="http://www.escomposlinux.org/jcantero/ld/2014/01/07/xpdf-poppler-fontconfig/">poppler</a>.</p>
<p><a href="https://pwmt.org/projects/zathura/">zathura</a> es evidentemente mucho más ligero que cualquier de
los dos, y además se usa con pulsaciones de teclado muy similares a las
de vim, pero le he encontrado algunas cosas incómodas. Para empezar, se
empeña en abrirme los documentos con un tamaño de ventana ridículamente
pequeño, y no guarda la última geometría usada. También es muy incómodo
hacer scroll, ya que el paso es muy pequeño y es cansado cuando tratas
de moverte rápidamente por las páginas. Supuestamente el paso de scroll
se puede configurar en el fichero <code>zathurarc</code>, pero no he conseguido una
velocidad lo suficientemente alta (como por ejemplo la que tiene
qpdfview).</p>
<p>Además, qpdfview tiene una característica muy útil de la que su
competencia carece (o al menos yo no la he visto): el modo de
visualización de 2 páginas a la vez. De esta manera se aprovecha el
enorme espacio horizontal del que disfrutamos en nuestros monitores
actuales con algo que es útil (nos permite volver la vista a la página
anterior inmediatamente en las páginas pares sin tener que pulsar ningún
botón).</p>
<p>Voy a usarlo durante una temporada, pero me sorprendería mucho si
tuviera que revisar mi decisión actual.</p>
<p>:wq</p>Reduciendo la instalación mínima de Debian Stretch2015-08-18T11:45:00+02:00Javier Canterotag:www.escomposlinux.org,2015-08-18:jcantero/ld/2015/08/18/reduciendo-la-instalacion-minima-de-debian-stretch/<p>En la actualización de hoy me he encontrado con que los siguientes
paquetes de mi instalación habían sido "degradados" a la prioridad
<em>optional</em>:</p>
<div class="highlight"><pre>i aptitude - terminal-based package manager
i at - Delayed job execution and batch pr
i bc - GNU bc arbitrary precision calcula
i bsd-mailx - simple mail user agent
i dc - GNU dc arbitrary precision reverse
i dnsutils - Clients provided with BIND
i exim4 - metapackage to ease Exim MTA (v4)
i exim4-base - support files for all Exim MTA (v4
i exim4-config - configuration for the Exim MTA (v4
i exim4-daemon-light - lightweight Exim MTA (v4) daemon
i ftp - classical file transfer client
i info - Standalone GNU Info documentation
i install-info - Manage installed documentation in
i m4 - macro processing language
i mlocate - quickly find files on the filesyst
i mutt - text-based mailreader supporting M
i nfs-common - NFS support files common to client
i patch - Apply a diff file to an original
i procmail - Versatile e-mail processor
i texinfo - Documentation system for on-line i
i time - GNU time program for measuring CPU
i w3m - WWW browsable pager with excellent
i whois - intelligent WHOIS client
</pre></div>
<p>Tras investigar un poco, me he encontrado con el <a href="https://lists.debian.org/debian-boot/2015/05/msg00156.html">siguiente mensaje en
<em>debian-boot</em></a>:</p>
<blockquote>
<p>I would like to re-evaluate what we change by default for Stretch,
that is the list of packages with priorities required, important and
standard. In general my plan involves installing less, taking into
consideration that requirements and expectations what should be
available in containers, chroots, on servers and desktop systems has
changed (at least IMHO).</p>
</blockquote>
<p>Este parece ser el origen y motivación de los cambios, mientras que los
cambios en sí se ha solicitado en el <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=788702">Bug 788702</a> y resuelto
(mediante los pertinentes modificaciones en el <em>FTP archive</em>) ayer 17 de
agosto. Tras ello, la cuenta de paquetes con prioridad <em>important</em> han
pasado de ser 64 a 58, y los de prioridad <em>standard</em> de 103 a 85 (los
valores previos proceden de <a href="http://www.escomposlinux.org/jcantero/ld/2015/05/20/radiografia-de-paquetes-instalados-en-debian/">Radiografía de paquetes instalados en
Debian</a><sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>).</p>
<p>Tengo un entorno <em>chroot</em> para compilar wine para 32 bits que he
intentado reducir a la mínima expresión, y todavía hay cosas (como el
sistema de init) que no he conseguido quitar y molestan. Así que estos
cambios —y todos los que sirvan para reducir la instalación mínima— son
bienvenidos.</p>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>también hay 2 paquetes <em>required</em> nuevos (hasta un total de 66),
pero esa nueva cifra no tiene nada que ver con estos cambios. <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>Errores de bind9 y logging2015-08-04T20:08:00+02:00Javier Canterotag:www.escomposlinux.org,2015-08-04:jcantero/ld/2015/08/04/errores-de-bind9-y-logging/<p>Desde que escribí <a href="http://www.escomposlinux.org/jcantero/ld/2013/12/03/logs-bind9-e-ipv6/">"Logs, bind9 e IPv6"</a> tenía
pendiente echar un vistazo al resto de mensajes que bind9 estaba
generando en los logs del sistema. Además de un montón de ruido inútil,
el problema es que a través de estos mensajes se filtra cierta cantidad
de información privada sobre los sitios que visitamos/accedemos (¡Hola
NSA!), tanto consciente como inconscientemente<sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>.</p>
<p>Mi proposito es por un lado reducir los mensajes que se están
registrando en los logs, dejando únicamente aquellos que realmente
merece la pena registrar, y por otro gestionar los logs de bind9 de
forma separada de los del resto del sistema para poder establecer
políticas de expiración diferentes. Afortunadamente bind9 tiene su
propio sistema de <em>logging</em> interno, por lo que no tendremos que
recurrir a jugar con la configuración de los logs del sistema.</p>
<h2>Logging en bind9</h2>
<p>La documentación oficial de bind9 describe <a href="http://ftp.isc.org/isc/bind9/cur/9.9/doc/arm/Bv9ARM.ch06.html#id2574875">la sintaxis para configurar
el sistema de <em>logging</em></a>. Este sistema se basa en dos
conceptos: los canales y las categorías. Los canales definen <strong>dónde</strong>
se mandarán los mensajes de log: a un fichero, al <em>syslog</em>, a la salida
estándar de error o a ningún sitio —<code>null</code>—. Además se pueden definir
algunos detalles adicionales, como el nivel de gravedad (<em>severity</em>)
mínimo de los mensajes, así como algunas opciones sobre campos a incluir
en cada mensaje de log —como un <em>timestamp</em> o la propia <em>severity</em>—.</p>
<p>Las categorías por su parte sirven para agrupar los mensajes de bind9
que tienen similar causa o subsistema de origen. Por ejemplo tenemos
categorías como <em>queries</em>, <em>network</em>, <em>database</em>, <em>security</em>, etc (para
una lista completa <a href="http://ftp.isc.org/isc/bind9/cur/9.9/doc/arm/Bv9ARM.ch06.html#id2574875">consultad la documentación</a>). El
sistema de <em>logging</em> de bind9 permite definir <strong>qué</strong> categorías de
mensajes se van a mandar a qué canales. Cada categoría puede mandarse a
varios canales, y de hecho la configuración por defecto (que es la que
se usa si no se indica nada) utiliza esto para mandar los mensajes de
log tanto a los logs del sistema como a un canal especial de debug. Es
lo mismo que si se hubiera escrito:</p>
<div class="highlight"><pre>logging {
category default { default_syslog; default_debug; };
category unmatched { null; };
};
</pre></div>
<p>La categoría <code>default</code> es la "recoge-todo": toda categoría para la que
no se definan canales usa los definidos en ésta. La categoría
<code>unmatched</code> es también especial y sólo sirve para recoger los mensajes
que por la razón que sea no tienen categoría. Como se puede observar,
estos mensajes sin categoría se ignoran (se mandan al canal <code>null</code>). Los
mensajes con categoría, como no hay definida ninguna otra categoría
aparte de <code>default</code>, acaban todos enviándose a los canales por defecto
<code>default_syslog</code> y <code>default_debug</code>. Estos dos canales están definidos
por defecto así:</p>
<div class="highlight"><pre>channel default_syslog {
syslog daemon;
severity info;
};
channel default_debug {
file "named.run";
severity dynamic;
};
</pre></div>
<p>El primer canal simplemente manda los mensajes de bind9 de gravedad
<em>info</em> o mayor al <em>syslog</em> —rsyslog, journald o el que sea—. En el caso
de rsyslog los mensajes acabarán normalmente en el fichero
<code>/var/log/syslog</code>. El segundo canal es como he dicho especial, y sirve
para hacer <em>debugging</em> de bind9. El nivel de la gravedad de los mensajes
de este canal es variable (<code>dynamic</code>) y depende del valor (un número
entre 1 y 99) pasado a named mediante la opcion <code>-d</code> de la línea de
comandos cuando se lanzó el proceso. Este valor también se puede cambiar
durante ejecución mediante los comando <code>rndc trace <valor></code> y <code>rndc
notrace</code>. El canal <code>default_debug</code> normalmente manda los mensajes de log
a un fichero, pero si se le ha indicado la opción <code>-f</code> a named en la
línea de comandos se usará en su lugar la salida de error estandar. Como
systemd por defecto manda la <em>stdout</em> y la <em>stderr</em> de los demonios que
arranca al <em>syslog</em>, y rsyslog almacena los mensajes <code>daemon.*</code> en
<code>/var/log/daemon.log</code>, los mensajes de bind9 terminan apareciendo por
duplicado en ambos ficheros de log.</p>
<p>Mi configuración va a ser diferente: no voy a mandar nada al <em>syslog</em>,
sino que guardaré todo en ficheros controlados directamente por named.
Lo primero de todo es crear el fichero de configuración de bind9 dónde
escribiré la configuración de <em>logging</em>. He decidido ponerla en un
fichero llamado <code>/etc/bind/named.conf.logging</code> separado del resto de los
ficheros de configuración para que las actualizaciones de paquetes no me
la pisen. Para que named lea este fichero hay que incluirlo desde
<code>/etc/named.conf</code>:</p>
<div class="highlight"><pre>include "/etc/bind/named.conf.logging";
include "/etc/bind/named.conf.options";
include "/etc/bind/named.conf.local";
include "/etc/bind/named.conf.default-zones";
</pre></div>
<p>Ahora pasemos a rellenar <code>/etc/bind/named.conf.logging</code>. Lo primero que
voy a hacer es definir mi propio canal al que llamaré <code>file_log</code>:</p>
<div class="highlight"><pre>logging {
channel file_log {
file "/var/log/bind9/named.log" versions 2 size 50k;
severity info;
print-time yes;
print-severity yes;
print-category yes;
};
category default { file_log; default_debug; };
category unmatched { null; };
};
</pre></div>
<p>Este canal manda los mensajes de log a un fichero llamado
<code>/var/log/bind9/named.log</code>. Es necesario crear dicho fichero de
antemano, y su propietario y grupo deben ser <code>bind:bind</code>. La <em>severity</em>
del nuevo canal es la misma que había por defecto (<em>info</em>) y además le
he indicado que añada a cada mensaje de log la fecha/hora en que se
produjo, la gravedad del mismo y la categoría a la que pertenece. En el
caso de <em>syslog</em> la fecha/hora es redundante, pero aquí si no la
activamos no sabremos cuando ocurrió cada mensaje. Los otros dos campos
simplemente me ayudarán en mi investigación.</p>
<p>No es necesario incluir este nuevo fichero en las políticas de
logrotate, ya que el propio bind9 permite declarar la política de
rotación de logs del fichero de un canal. La palabra clave <code>versions</code>
nos permite indicar cuántas rotaciones (ficheros) queremos tener como
máximo, y si añadimos <code>size</code> se limitará el tamaño máximo que alcanzará
el fichero de log antes de rotar (si no se rotará cada vez que se
arranque o recargue named).</p>
<p>Pero hay un pequeño problema: named va a tratar de crear los distintos
ficheros de rotación en el mismo directorio que el fichero de log, y
normalmente lo hace ejecutándose como usuario <em>bind</em>. Si el directorio
del fichero de log no permite escribir ficheros al usuario <em>bind</em> (como
es el caso de <code>/var/log</code> que es propiedad de <em>root</em>), esto va a provocar
errores de permisos cada vez que se intenten rotar los logs. Es por esta
razón por la que arriba he puesto el fichero de log dentro de un
subdirectorio <code>/var/log/bind9/</code> cuyo propietario es <code>bind:bind</code> y en el
que named pueda guardar y rotar los ficheros sin problemas.</p>
<p>Como mi objetivo es limitar la cantidad de información que pueda
filtrarse a través de este fichero, he puesto una política muy agresiva
de "olvido" (sólo dos ficheros de log de 50 KB cada uno como máximo). En
teoría no debería ser mayor problema, ya que, una vez bien configuradas
las categorías de mensajes, el número de líneas del fichero debería ser
mínimo.</p>
<h2>Errores y categorías</h2>
<p>A continuación pondré una lista de distintos mensajes de log que he
encontrado durante un pequeño periodo de pruebas. He ocultado los datos
de dominios e IPs (se dice el pecado pero no el pecador. <code>;-)</code>) y he
incluido los campos de categoría y <em>severity</em> para el posterior
análisis:</p>
<div class="highlight"><pre>resolver: notice: DNS format error from XX.XX.XX.XX#53 resolving www.ejemplo.dom/AAAA for client 127.0.0.1#33333: Name ejemplo.dom (SOA) not subdomain of zone www.ejemplo.dom -- invalid response
lame-servers: info: error (FORMERR) resolving 'www.ejemplo.dom/AAAA/IN': XX.XX.XX.XX#53
lame-servers: info: error (unexpected RCODE REFUSED) resolving 'www.ejemplo.dom/AAAA/IN': XX.XX.XX.XX#53
lame-servers: info: error (unexpected RCODE SERVFAIL) resolving 'www.ejemplo.dom/A/IN': XX.XX.XX.XX#53
lame-servers: info: error (connection refused) resolving 'www.ejemplo.dom/A/IN': XX.XX.XX.XX#53
lame-servers: info: lame server resolving 'www.ejemplo.dom' (in 'ejemplo.dom'?): XX.XX.XX.XX#53
edns-disabled: info: success resolving 'www.ejemplo.dom/A' (in 'ejemplo.dom'?) after reducing the advertised EDNS UDP packet size to 512 octets
edns-disabled: info: success resolving 'www.ejemplo.dom/A' (in 'www.ejemplo.dom'?) after disabling EDNS
dnssec: info: validating @0x7fxxxxxxxxxx: www.ejemplo.dom A: no valid signature found
dnssec: info: validating @0x7fxxxxxxxxxx: www.ejemplo.dom AAAA: no valid signature found
dnssec: info: validating @0x7fxxxxxxxxxx: ejemplo.dom SOA: no valid signature found
dnssec: info: validating @0x7fxxxxxxxxxx: www.ejemplo.dom NSEC: no valid signature found
</pre></div>
<p>Estos son los mensajes más repetidos, especialmente los dos primeros que
vienen en pareja. También he encontrado otros mucho menos frecuentes:</p>
<div class="highlight"><pre>resolver: notice: DNS format error from XX.XX.XX.XX#53 resolving www.ejemplo.dom/AAAA for client 127.0.0.1#44444: non-improving referral
lame-servers: info: error (insecurity proof failed) resolving 'ejemplo.dom/DNSKEY/IN': XX.XX.XX.XX#53
lame-servers: info: error (no valid DS) resolving 'www.ejemplo.dom/A/IN': XX.XX.XX.XX#53
lame-servers: info: error (no valid RRSIG) resolving 'ejemplo.dom/DS/IN': XX.XX.XX.XX#53
dnssec: info: validating @0x7fxxxxxxxxxx: ejemplo.dom DNSKEY: got insecure response; parent indicates it should be secure
</pre></div>
<p>La <em>severity</em> de todos estos mensajes es <em>info</em> salvo para los dos
mensajes de la categoría <em>resolver</em> que son <em>notice</em>, así que se podría
simplemente indicar un <code>severity warning;</code> en el canal para descartar
todos estos mensajes. Pero, y es aquí es cuando podemos empezar a intuir
los inconvenientes del diseño del sistema de <em>logging</em> de bind9, así
descartaríamos también cualquier otro mensaje de gravedad <em>info</em> o
<em>notice</em>. Es por esa causa por la que se implementan las categorías, ya
que éstas permiten una forma más específica de tratar los distintos
mensajes.</p>
<p>Las categorías a las que pertenecen estos mensajes son: <em>lame-servers</em>,
<em>resolver</em>, <em>dnssec</em> y <em>edns-disabled</em>. De ellas, <em>lame-servers</em> es la
primera candidata a descartar, ya que es una categoría que reune
precisamente el tipo de mensajes que genera bind9 cuando se encuentra
con que otro servidor no está comportándose como debiera, e informa de
ello. Como en estos casos es siempre el otro servidor está mal
configurado, y raramente podemos hacer algo al respecto, estos mensajes
son de los que no merece la pena informar al administrador y por lo
tanto ignoraremos la categoría entera mandándola al canal <code>null</code>. Esta
es una configuración muy común, pero por alguna razón —al menos en
Debian— no viene por defecto.</p>
<p>Las otras 3 categorías en principio me van a requerir una investigación
más profunda. He encontrado este bug <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=584557">#584557</a> en el BTS de
Debian en el que que se solicita descartar las categorías <em>resolver</em> y
<em>edns-disabled</em>:</p>
<blockquote>
<p>Please suppress the "resolver" log category, on the grounds that it
spams the system log a great deal, and just like "edns-disabled" and
"lame-servers", refers to issues completely outside of the hability of
the local nameserver operator to fix, AND extremely unlikely to get
fixed even if reported.</p>
<p>[...]</p>
<p>Sideway referals are very common practice in the ARIN region, most
people either don't care, or don't even understand that they introduce
undue latency. Even clueful admins like the kernel.org people use them.
I bet we have some of that in debian.org/debian.net as well.</p>
<p>As for the invalid response, a very common cause for that are broken
load-balancer setups. Just like the ECN IP functionality, tracking this
is a lost cause that will fix itself in a couple decades and will resist
any efforts to accelerate the process (unless, say, someone from the top
tier like Google decides to use a massive large hammer and face lawsuits
over it).</p>
</blockquote>
<p>No es la única referencia que he encontrado que atribuye esos mensajes
de <em>resolver</em> y sus FORMERR asociados a <a href="http://fanf.livejournal.com/107721.html">problemas con load balancers
mal configurados</a>. De todas formas el bug
(fusionado con el <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=492901">##492901</a>) sigue 6 años despues abierto,
aunque puede deberse simplemente a que el mantenimiento del paquete
bind9 en Debian parece centrado exclusivamente en cerrar agujeros de
seguridad.</p>
<p>Los mensajes de <em>edns-disabled</em> por su parte parece que se deben a
<a href="http://sysadminthings.blogspot.com.es/2011/09/things-i-never-knew-about-dns-edns.html"><em>firewalls</em> mal configurados que filtran los paquetes EDNS de más de
512 bytes</a>. Los mensajes se pueden eliminar también de otra
forma: reduciendo el tamaño de los paquetes EDNS recibidos a 512 bytes
mediante la opción<sup id="fnref:2"><a class="footnote-ref" href="#fn:2" rel="footnote">2</a></sup> <code>edns-udp-size 512;</code>. Pero esta opción anula la
razón de ser de la extensión EDNS (que es emplear paquetes UDP de hasta
4096 bytes) y haría que la resolución en general fuera más lenta. El
manual de bind9 <a href="http://ftp.isc.org/isc/bind9/cur/9.9/doc/arm/Bv9ARM.ch06.html#options">dice acerca de esta opción</a>:</p>
<blockquote>
<p><strong>edns-udp-size</strong></p>
<p>Sets the advertised EDNS UDP buffer size in bytes to control the size
of packets received. Valid values are 512 to 4096 (values outside
this range will be silently adjusted). The default value is 4096. The
usual reason for setting edns-udp-size to a non-default value is to
get UDP answers to pass through broken firewalls that block
fragmented packets and/or block UDP packets that are greater than 512
bytes.</p>
<p>named will fallback to using 512 bytes if it get a series of timeout
at the initial value. 512 bytes is not being offered to encourage
sites to fix their firewalls. Small EDNS UDP sizes will result in the
excessive use of TCP.</p>
</blockquote>
<p>Creo que la decisión más inteligente en este caso es seguir usando EDNS
con 4096 bytes, que es más óptimo, e ignorar los mensajes provenientes
de servidores DNS tras <em>firewalls</em> mal configurados, que son —espero—
una minoría.</p>
<p>La última categoría problemática es la de <em>dnssec</em>, que son los mensajes
debidos al uso de las extensiones de seguridad de DNS
<a href="https://en.wikipedia.org/wiki/Domain_Name_System_Security_Extensions">DNSSEC</a>. Este es un tema complejo y no parece que haya
mucha gente que controle del mismo, así que parte de las respuestas que
he encontrado consisten directamente en desactivar la validación DNSSEC.
Del resto, la respuesta más repetida es la de <a href="https://jackson-brain.com/bind-configuration-and-dnssec-validating-no-signature-found/">usar la opción
<code>dnssec-validation auto;</code> en vez de <code>dnssec-validation
yes;</code></a>, pero resulta que, en el caso de Debian, esta
opción ya viene en el fichero de opciones<sup id="fnref:2"><a class="footnote-ref" href="#fn:2" rel="footnote">2</a></sup>. A partir de ahí, lo
máximo que he conseguido averiguar es que los mensajes <em>got insecure
response; parent indicates it should be secure</em> indica posiblemente una
configuracion incorrecta del DNSSEC del servidor interrogado, y que el
caso de los <em>no valid signature found</em> podría (y aquí las cosas no están
muy claras) ser también por culpa de la fragmentación de paquetes UDP al
pasar por <em>firewalls</em> "problemáticos".</p>
<p>Al final, lo que he decidido es ignorar también todos estos mensajes de
categoría <em>dnssec</em> ya que estamos en la misma situación que con los
<em>lame-servers</em> y demás: son mensajes sobre problemas que están más allá
de nuestro control. Pero no me hace mucha gracia perder los mensajes de
esta categoría con <em>severity</em> alta (errores serios de validación). Para
esto necesito otro canal con una <em>severity</em> diferente, pero como dudo
que bind9 permita a dos canales compartir el mismo fichero de log,
necesito un destino distinto para el canal. No quiero usar otro fichero
y tener que rotarlo, etc, así que al final, aunque había dicho de no
utilizar el <em>syslog</em>, me he definido mi propio canal <code>errors_syslog</code>
para recoger los mensajes graves (de <em>severity warning</em> o mayor) en él.
El sistema de <em>logging</em> de bind9 no es tan flexible como pudiera parecer
a primera vista, y en casos como éste queda en evidencia.</p>
<p>Podría hacer lo mismo con las otras tres categorías, pero he comprobado
en el código fuente de bind9 (concretamente el de la versión 9.9.5 que
uso) que los mensajes de categorias <em>lame-servers</em> y <em>edns-disabled</em> son
todos de gravedad <em>info</em> y los de <em>resolver</em> son mayoritariamente
<em>notice</em> o <em>debug</em> (hay alguna excepción que es <em>warning</em>). Por ello
esas categorías las voy a ignorar totalmente<sup id="fnref:3"><a class="footnote-ref" href="#fn:3" rel="footnote">3</a></sup>, y la versión final de
mi <code>named.conf.logging</code> queda por lo tanto así:</p>
<div class="highlight"><pre>logging {
channel file_log {
file "/var/log/bind9/named.log" versions 2 size 50k;
severity info;
print-time yes;
print-severity yes;
print-category yes;
};
channel errors_syslog {
syslog daemon;
severity warning;
};
category lame-servers { null; };
category edns-disabled { null; };
category resolver { null; };
category dnssec { errors_syslog; };
category default { file_log; errors_syslog; default_debug; };
category unmatched { null; };
};
</pre></div>
<p>No obstante, lo vigilaré durante una temporada por si hay que hacer
ajustes a posteriori.</p>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>y es que normalmente no nos damos cuenta de la cantidad de
conexiones que se están produciendo entre bambalinas cada vez
que accedemos a un sitio: <em>widgets</em>, <em>ads</em>, <em>trackers</em>,
herramientas analíticas, objetos incrustados y demás porquería <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>dentro de la sección <code>options { ... };</code>, que en Debian está en
el fichero <code>/etc/bind/named.conf.options</code> <a class="footnote-backref" href="#fnref:2" rev="footnote" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:3">
<p>otra alternativa sería usar <code>default_debug</code> para que sólo se mostraran
los mensajes cuando se activara el debug <a class="footnote-backref" href="#fnref:3" rev="footnote" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
</ol>
</div>Llega ffmpeg a Stretch2015-07-21T19:55:00+02:00Javier Canterotag:www.escomposlinux.org,2015-07-21:jcantero/ld/2015/07/21/llega-ffmpeg-a-stretch/<p>Los primeros paquetes de ffmpeg (véase <a href="http://www.escomposlinux.org/jcantero/ld/2015/07/08/ffmpeg-volvera-a-debian/">"FFmpeg volverá a
Debian"</a><sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>) están empezando a llegar a Debian Stretch
poco a poco, mediante cambios en las dependencias en las principales
aplicaciones que usan estas bibliotecas (por ejemplo en mi caso mplayer2
y mpv). En concreto, esta mañana:</p>
<div class="highlight"><pre>Se instalarán los siguiente paquetes NUEVOS:
libavcodec-ffmpeg56{a} libavformat-ffmpeg56{a} libavresample-ffmpeg2{a} libavutil-ffmpeg54{a} libcrystalhd3{a} libshine3{a} libsoxr0{a}
libssh-gcrypt-4{a} libswresample-ffmpeg1{a}
Se actualizarán los siguientes paquetes:
libasound2-plugins libgegl-0.2-0 libopencv-core2.4 libopencv-imgproc2.4 libx264-146 ...
</pre></div>
<p>Y hace un rato:</p>
<div class="highlight"><pre>Se instalarán los siguiente paquetes NUEVOS:
libavdevice-ffmpeg56{a} libavfilter-ffmpeg5{a} libpgm-5.1-0{a} libpostproc-ffmpeg53{a} libsodium13{a} libswscale-ffmpeg3{a} libzmq3{a}
Se ELIMINARÁN los siguientes paquetes:
libavdevice55{u} libavfilter5{u} libpostproc52{u} libswscale3{u}
Se actualizarán los siguientes paquetes:
mplayer2 mpv
</pre></div>
<p>Técnicamente, la <a href="https://release.debian.org/transitions/html/ffmpeg-libav.html">transición de los paquetes de libav a los de
ffmpeg</a> se va a hacer añadiendo paquetes con el mismo
nombre más <code>"-ffmpeg"</code>. Por eso <code>libavdevice55</code> es reemplazado por
<code>libavdevice-ffmpeg56</code>, y así con el resto. Podéis consultar la lista de
los nuevos paquetes binarios en <a href="https://packages.debian.org/source/stretch/ffmpeg">src:ffmpeg</a> o el
<a href="https://packages.qa.debian.org/f/ffmpeg.html">PTS</a> pero este diagrama de dependencias es (creo yo) mucho
más informativo:</p>
<p><img alt="Paquetes de ffmpeg y sus dependencias" src="http://www.escomposlinux.org/jcantero/ld/images/ffmpeg-packages-small.png" /></p>
<p><a href="http://www.escomposlinux.org/jcantero/ld/images/ffmpeg-packages.png">(Versión Grande)</a> - <a href="http://www.escomposlinux.org/jcantero/ld/files/ffmpeg-packages.dot">(Dot)</a></p>
<p>De estos 9 paquetes, 4 implementan el <em>core</em> de la funcionalidad de
ffmpeg en forma de bibliotecas, y otros 5 son bibliotecas de apoyo (una
de ellas de transición). En concreto:</p>
<ul>
<li><code>libavcodec-ffmpeg</code>: <em>codecs</em> de codificación/decodificación de audio
y video (alternativamente se puede sustituir por el paquete
<code>libavcodec-ffmpeg-extra</code> que contiene algunos codecs adicionales)</li>
<li><code>libavdevice-ffmpeg</code>: abstrae el manejo de los distintos
dispositivos/APIs multimedia (Video4Linux2, ALSA, etc) adonde enviar
(o de dónde recibir) el audio y video procesado o a procesar</li>
<li><code>libavfilter-ffmpeg</code>: proporciona el soporte genérico para filtros de
audio y video</li>
<li><code>libavformat-ffmpeg</code>: proporciona soporte para distintos formatos
contenedores de audio, video y subtítulos, así como para el
multiplexado y demultiplexado de los mismos</li>
<li><code>libswscale-ffmpeg</code>: biblioteca de apoyo para el reescalado de
videos y conversión entre formatos de pixel</li>
<li><code>libpostproc-ffmpeg</code>: biblioteca de apoyo para postprocesado de video</li>
<li><code>libswresample-ffmpeg</code>: biblioteca de apoyo para conversiones en el
audio como <em>resampling</em>, transformaciones de canales o de formatos</li>
<li><code>libavresample-ffmpeg</code>: se proporciona únicamente por compatibilidad
hacia atrás, es preferible usar <code>libswresample</code></li>
<li><code>libavutil-ffmpeg</code>: facilita la vida al resto de bibliotecas de
ffmpeg proporcionando funciones auxiliares portables y seguras (de
manejo de strings, matemáticas, de números aleatorios, etc)</li>
</ul>
<p><strong>Actualización (2015-07-26):</strong> en mi instalación puedo dar por
concluida la migración, ya que el último paquete con dependencias de
libav (<code>gstreamer1.0-libav</code>) se ha actualizado hoy para pasar a depender
de las bibliotecas de ffmpeg, y los últimos paquetes de libav que
quedaban han sido desinstalados:</p>
<div class="highlight"><pre>Se ELIMINARÁN los siguientes paquetes:
libavcodec-extra-56{u} libavformat56{u} libavresample2{u} libavutil54{u}
</pre></div>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>recomiendo también el <a href="http://lwn.net/Articles/650816/">extenso artículo</a> que LWN
ha publicado recientemente sobre el tema. <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>Transición a GCC5 en Debian2015-07-19T12:17:00+02:00Javier Canterotag:www.escomposlinux.org,2015-07-19:jcantero/ld/2015/07/19/transicion-a-gcc5-en-debian/<p>Este <a href="https://lists.debian.org/debian-devel-announce/2015/07/msg00000.html">mensaje</a> en la lista de correo <code>debian-devel-announce</code>
detalla los planes para la transición de Debian a <a href="http://www.escomposlinux.org/jcantero/ld/2015/04/23/ha-salido-gcc-5-perdon-gcc-51/">las versiones 5.x de
GCC</a>, así como a la nueva versión de la biblioteca estándar de
C++ <code>libstdc++6</code>:</p>
<blockquote>
<p>Compared to earlier version bumps, the switch to GCC 5 is a bit more
complicated because libstdc++6 sees a few ABI incompatibilities,
partially depending on the C++ standard version used for the builds.
For some C++11 language requirements, changes on some core C++
classes are needed, resulting in an ABI change.</p>
</blockquote>
<p>No sólo cambia el ABI, GCC 5.x también cambia el estándar que se compila
por defecto a <a href="https://en.wikipedia.org/wiki/C%2B%2B11">C++11</a> (y la próxima versión GCC 6 lo volverá a
cambiar a <a href="https://en.wikipedia.org/wiki/C%2B%2B14">C++14</a>), por lo que los paquetes deben o bien indicar
explícitamente a GCC que se use C++98 (opciones <code>-std=c++98</code> o
<code>-std=gnu++98</code>), o bien asegurarse que los fuentes compilan
correctamente con C++11.</p>
<p>Para tratar de mitigar con antelación los problemas que iba a acarrear
de la transición a C++11 se abrieron más de <a href="https://bugs.debian.org/cgi-bin/pkgreport.cgi?tag=ftbfs-gcc-5;users=debian-gcc@lists.debian.org">470 bugs FTBFS</a>
(Failed To Build From Source) en el Bug Tracking System, de los cuales
ya hay resueltos más de 260, pero todavía quedan más de 200 por
resolver. Mientras tanto, el día 31 de julio, que es cuando GCC cambiará
de versión en el archivo de Debian, se aproxima. Así que agarraros
porque en unas dos semanas (más 5 días para pasar de Sid a Testing)
vienen curvas.</p>
<p>Estos son por supuesto los inconvenientes de querer vivir al límite
(también en Debian).</p>
<p>Para más información consulta la <a href="https://wiki.debian.org/GCC5">página del wiki sobre la transición a
GCC5</a>.</p>
<p>:wq</p>Más motivos para usar licencias copyleft2015-07-17T19:46:00+02:00Javier Canterotag:www.escomposlinux.org,2015-07-17:jcantero/ld/2015/07/17/mas-motivos-para-usar-licencias-copyleft/<p>La última entrada del blog de Bradley M. Kuhn <a href="http://ebb.org/bkuhn/blog/2015/07/15/ubuntu-ip-policy.html">Thoughts on Canonical,
Ltd.'s Updated Ubuntu IP Policy</a> lo expresa mejor que yo:</p>
<blockquote>
<p>Therefore, this whole situation is a simple and clear argument for
why copyleft matters. Copyleft can and does (when someone like me
actually enforces it) prevent such situations. But copyleft is not
infinitely expansive. Nearly every full operating system distribution
available includes an aggregated mix of copylefted, non-copyleft, and
often fully-proprietary userspace applications. Nearly every company
that distributes them wraps the whole thing with some agreement that
restricts some rights that copyleft defends, and then adds a trump
clause that gives an exception just for FLOSS license compliance.
Sadly, I have yet to see a company trailblaze adoption of a “software
freedom preservation” clause that guarantees copyleft-like compliance
for non-copylefted programs and packages.</p>
</blockquote>
<p>Las licencias no copyleft, en su intento de ser "liberales" por el
método de incluir el menor número de claúsulas posibles, dejan muchos
agujeros a los que se aferran luego comportamientos que poco tienen que
ver con el espíritu del software libre, como es este de Canonical y sus
reclamaciones sobre "la licencia de sus paquetes binarios". La FSF y la
SFC les han puesto los puntos sobre las íes en el caso de los binarios
de paquetes bajo licencia GPL, gracias a que esa licencia cubre
perfectamente los derechos de los receptores de los paquetes binarios.
Pero para paquetes cuyas fuentes usan licencias tipo MIT, BSD, etc no
hay nada que hacer, ya que dichas licencias no contemplan estos casos, y
Canonical o cualquiera pueden arrogarse con la "propiedad intelectual"
de los binarios compilados, por muy absurdo que pueda parecer.</p>
<p>Este no es más que otro pequeño motivo que añadir a la ya larga lista de
razones para preferir usar licencias <em>copyleft</em> frente a las no
<em>copyleft</em>, pero nunca está de más mostrar en la vida real cuáles son
las consecuencias de elegir un tipo u otro de licencia. Más que nada,
porque los que van pregonando la supuesta superioridad de las licencias
no <em>copyleft</em> no os van a contar estos "pequeños detalles" (ellos suelen
estar más preocupados pensando en cómo sacar provecho de vuestro trabajo
para su propio beneficio).</p>
<p>Luego aparte está el caso de Canonical y su enorme hipocresía. Le
quieren negar a los demás (Linux Mint, etc) la posibilidad de hacer
distribuciones derivadas de Ubuntu, cuando Ubuntu no es más que un <em>free
rider</em> de otra distribución —Debian—. <em>"Reglas vendo que para mi no
tengo"</em>. Y encima los malos son los demás, que son muy injustos con
ellos y no hacen más que criticarles.</p>
<p>Yo me pensaría seriamente "regalarle" mi trabajo a gente de esta
catadura moral, que es lo que se consigue poniéndolo bajo una licencia
no <em>copyleft</em>.</p>
<p>:wq</p>Pasa de Flash y ve videos nativamente con mpv2015-07-15T21:09:00+02:00Javier Canterotag:www.escomposlinux.org,2015-07-15:jcantero/ld/2015/07/15/pasa-de-flash-y-ve-videos-nativamente-con-mpv/<p>La enésima vulneabilidad del <em>plugin</em> de Flash ha sido la gota que ha
colmado el vaso. No sólo ha provocado que mucha gente esté pidiendo
acabar con este programa propietario —y estoy hablando de gente de peso—
sino que la gente de Mozilla, cansada, ha hecho que Firefox haya
desactivado por defecto el <em>plugin</em>. La medida parece ser temporal
—hasta que salga una nueva actualización que arregle los bugs de
seguridad que se han conocido— pero este puede ser una buena excusa para
<a href="http://occupyflash.org/">acabar de una vez por todas con el odioso <em>plugin</em></a>.</p>
<p>Así que, para los que usan Flash exclusivamente para ver videos en
YouTube y sitios similares (que es la mayoría de la gente), voy a
ofrecer una alternativa que estoy probando y me está pareciendo
fantástica. Sí, sí, ya sé que la alternativa real es HTML5, pero
mientras llega, si tienes que lidiar con sitios que todavía sólo
funcionan con Flash, esta puede ser una solución temporal.</p>
<p>Se trata de usar el reproductor nativo <a href="http://mpv.io/">mpv</a><sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup> junto con
<a href="http://youtube-dl.org/">youtube-dl</a>, una herramienta que permite ver <em>streamings</em> no sólo
de YouTube sino de <a href="https://rg3.github.io/youtube-dl/supportedsites.html">un montón de sitios más</a>. Lo bueno es que
ambos ya están integrados: basta que youtube-dl esté instalado para que
mpv pueda reproducir nativamente cualquier video de uno de los sitios
soportados con tan sólo indicarle la URL:</p>
<div class="highlight"><pre>mpv https://www.youtube.com/watch?v=bS5P_LAqiVg
</pre></div>
<p>Aclarar que youtube-dl funciona en modo streaming, por lo que puedes
saltar hasta el momento que quieras usando la interfaz o las teclas de
mpv sin que por detrás se esté descargando el video completo.</p>
<p>Sólo falta un detalle más: la integración con Firefox (más que nada,
porque es un poco pesado estar copiando y pegando URLs). Para ello se
puede usar un <em>add-on</em> genérico como <a href="https://addons.mozilla.org/en-US/firefox/addon/open-with/">Open With</a> o uno
específico como <a href="https://addons.mozilla.org/en-US/firefox/addon/watch-with-mpv/">Watch with MPV</a><sup id="fnref:2"><a class="footnote-ref" href="#fn:2" rel="footnote">2</a></sup>, dependiendo de si se
quiere usar para más cosas o si se prefiere un botón rápido
exclusivamente para lanzar la reproducción del video.</p>
<p>He instalado este último y, siendo algo tan simple (un botón que cuando
se pulsa invoca mpv con la URL actual), es sin embargo tremendamente
cómodo y funcional. Es tan gratificante poder ver los videos no ya sin
usar Flash, sino sin ni siquiera activar el Javascript...</p>
<p>Probadlo y no os arrepentiréis. <code>;-)</code></p>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>mpv es <em>fork</em> de mplayer/mplayer2 cuyo desarrollo (al contrario
que sus predecesores) sigue activo en la actualidad. <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>Soy consciente de la poca gente que lo usa, pero no he
encontrado otro. Además, un <a href="https://github.com/antoniy/mpv-youtube-dl-binding">vistazo a las fuentes</a>
es suficiente para ver que no hace nada remotamente "raro". <a class="footnote-backref" href="#fnref:2" rev="footnote" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
</ol>
</div>PulseAudio y Xfce2015-07-09T18:57:00+02:00Javier Canterotag:www.escomposlinux.org,2015-07-09:jcantero/ld/2015/07/09/pulseaudio-y-xfce/<p>Al final del artículo <a href="http://www.escomposlinux.org/jcantero/ld/2015/05/27/instalando-pulseaudio-en-debian-jessie/">Instalando PulseAudio en Debian
Jessie</a> comentaba que me quedaban unos cuantos molestos
detalles por solucionar con PulseAudio:</p>
<ul>
<li>Al pulsar el botón multimedia de "Mute" para hacer un <em>unmute</em>, el
sonido permanece en silencio porque sólo se ha reactivado el canal
"Master" del mixer de sonido, mientras que el resto de canales (en mi
caso "Headphone" y "Front") permanecen silenciados (que
correspondería con el <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=654633">bug #654633</a> del BTS).</li>
<li>Los botones multimedia de subir/bajar volumen sólo funcionan para la
tarjeta de sonido ALSA configurada. Específicamente no funcionan para
ningún otro <em>sink</em> de sonido PulseAudio aunque esté activo (como mi
<em>headset</em> bluetooth).</li>
</ul>
<p>A estos dos bugs del pasado artículo tengo que añadir este otro:</p>
<ul>
<li>Los sonidos que acompañan las ventanas emergentes de pausa de
Workrave producen dos molestas notificaciones de cambio de volumen
(tiene pinta de ser el mismo que el <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=754155">bug #754155</a>).</li>
</ul>
<p>Estos "flecos" tienen que ver con la integración de PulseAudio con
<a href="http://www.xfce.org/">Xfce</a><sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>, o mejor dicho con la ausencia de integración de
PulseAudio con Xfce.</p>
<p>Xfce tiene 2 componentes relacionados con el sistema de sonido:</p>
<ul>
<li>
<p><strong>xfce4-mixer</strong>: la típica aplicación de control de volúmenes
—mixer— de los distintos dispositivos de entrada y salida de sonido.
Es una aplicación independiente aunque también puede funcionar como
un plugin de panel de Xfce.
<img alt="xfce4-mixer" src="http://www.escomposlinux.org/jcantero/ld/images/xfce4-mixer.png" /></p>
</li>
<li>
<p><strong>xfce4-volumed</strong>: un demonio que permite controlar el volumen de una
tarjeta (la seleccionada en la configuración) mediante las teclas
multimedia de volumen. También se encarga de mostrar visualmente
los cambios de volumen mediante notificaciones.
<img alt="xfce4-volumed" src="http://www.escomposlinux.org/jcantero/ld/images/xfce4-volumed.png" /></p>
</li>
</ul>
<p>La cuestión es que ambas aplicaciones interaccionan con el subsistema de
sonido a través de GStreamer (0.10) en vez de usar ALSA o PulseAudio
directamente, y es GStreamer el que se encarga de usar el <em>backend</em>
apropiado. En Debian esto se traduce en que tanto <a href="https://packages.debian.org/jessie/xfce4-mixer">xfce4-mixer</a>
como <a href="https://packages.debian.org/jessie/xfce4-volumed">xfce4-volumed</a> tienen una dependencia del paquete
<code>gstreamer0.10-alsa</code> <strong>o alternativamente</strong> del <a href="https://packages.debian.org/jessie/gstreamer0.10-audiosink">paquete virtual
<code>gstreamer0.10-audiosink</code></a> (que provee entre otros el
paquete <code>gstreamer0.10-pulseaudio</code>). Así que dependiendo de si usamos
ALSA o PulseAudio debemos tener instalado el paquete del <em>backend</em> de
GStreamer que corresponda.</p>
<p>Por desgracia, me temo que los desarrolladores de Xfce se preocupan
esencialmente de la integración con ALSA, y por eso la dependencia con
<code>gstreamer0.10-alsa</code> es más prioritaria que el resto. Esto hace que casi
siempre acabe instalandose <code>gstreamer0.10-alsa</code> (sobre todo si
previamente se tenía una instalación con ALSA como es mi caso), lo que a
su vez provoca que <code>apt</code> o <code>aptitude</code> no encuentren necesario instalar
<code>gstreamer0.10-pulseaudio</code>. En la práctica es fácil encontrarse en la
situación de no tener instalado este <em>backend</em> a pesar de tener
instalado PulseAudio, y esa como veremos luego es una de las razones de
la existencia de estos bugs.</p>
<p>Otra de razones es que simplemente las aplicaciones no están pensadas
con la arquitectura de PulseAudio en mente. Están hechas para un tiempo
en el que el sistema de sonido consistía en un único dispositivo
hardware estático al que mandar el audio, y como mucho del que
recibirlo. Escenarios como conectar un <em>headset</em> Bluetooth y que el
audio tenga automáticamente que migrar a este nuevo dispositivo no se
concebían entonces, pero actualmente se asume que el sistema tiene que
soportarlos (es lo que pasa por ejemplo en el <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=677014">bug #677014</a>).</p>
<p>Esto lleva a casos como el del propio mantenedor de xfce4-volumed
diciendo que su aplicación <a href="https://bugs.launchpad.net/xfce4-volumed/+bug/883485/comments/4">no es compatible con
PulseAudio</a>. El problema que tiene este desarrollador no es
adaptar su aplicación a una nueva API, es que tendría que rediseñarla de
arriba a abajo basándose en el nuevo modelo dinámico de PulseAudio. Y la
impresión que me da es que no está muy por la labor.</p>
<p>A esto hay que añadir que el mismo autor considera a día de hoy
xfce4-volumed como <a href="https://launchpad.net/xfce4-volumed">sin mantenimiento</a>:</p>
<blockquote>
<p><em>XVD is no longer maintained</em> It relies on libkeybinder and gst-0.10,
both of which are superseded, and it needs to integrate a longstand
PulseAudio support patch. I will, eventually, rewrite xvd with
libxfce4utils instead of libkeybinder and gst1.0 instead of gst-0.10.
If you want to contribute to Xfce by fixing an old but useful piece
of code, get in touch with me!</p>
</blockquote>
<p>lo que queda corroborado por el hecho de que la última versión que hay
—la 0.1.13— en el <a href="http://git.xfce.org/apps/xfce4-volumed">repositorio git oficial</a> es de marzo de 2011.</p>
<p>El parche de soporte de PulseAudio al que se refiere debe ser
<a href="https://launchpad.net/xfce4-volumed-pulse">xfce4-volumed-pulse</a>. El autor del mismo
<a href="https://bugs.launchpad.net/xfce4-volumed/+bug/883485/comments/40">explica</a>:</p>
<blockquote>
<p>The developer of xfce4-volumed said that xfce4-volumed isn't
compatible with pulseaudio, but that's not really accurate. The first
problem is a default settings issue (preselection of the correct gst
card/channel), and the second culprit is gstreamer pulse plugin is
one culprit (basically, the bindings suck, let's say it).</p>
<p>[...]</p>
<p>A few months ago, I "forked" xfce4-volumed and ported it locally to
pulseaudio. It works fine here (it takes the default pulse card, you
can't change it with xfconf-query anymore, but with pactl or the
pulseaudio mixer), but it didn't have many testing and I haven't had
time to include it in Xubuntu anyway.</p>
</blockquote>
<p>La pega es que si se quiere usar xfce4-volumed-pulse hay que compilarlo
e instalarlo a mano. No está empaquetado en Debian<sup id="fnref:2"><a class="footnote-ref" href="#fn:2" rel="footnote">2</a></sup> y tampoco he
visto ningúna <a href="https://wiki.debian.org/RFP">petición</a> o <a href="https://wiki.debian.org/ITP">intento</a> de empaquetarlo.</p>
<p>De todas formas xfce4-volumed-pulse es una solución justo para salir del
paso. Como dice su desarrollador, xfce4-volumed tiene que reescribirse
aunque sólo sea porque hay que migrar la aplicación de GStreamer 0.10 a
GStreamer 1.x (ya expliqué hace poco que GStreamer 0.10 está llamado a
desaparecer y <a href="http://www.escomposlinux.org/jcantero/ld/2015/07/06/borrado-de-gstreamer-010-para-debian-stretch/">Debian no lo va a incluir más a partir de
Stretch</a>). Y además hay otros cambios pendientes en
la infraestructura de bibliotecas de soporte de Xfce que exigen una
nueva reimplementación. Puede ser el momento apropiado para empezar
desde cero y arreglar todo de una vez.</p>
<p>La situación de xfce4-mixer es muy parecida: puede considerarse en
estado "sin mantenimiento". La última versión estable es la 4.10 de
octubre de 2012 y hay una primera <a href="https://mail.xfce.org/pipermail/xfce-announce/2014-April/000321.html">versión de desarrollo 4.11</a>
de abril de 2014, pero desde entonces <a href="http://git.xfce.org/apps/xfce4-mixer">el repositorio git</a> no
se ha tocado salvo para actualizar traducciones. Y encima cuando abren
un bug <a href="https://bugzilla.xfce.org/show_bug.cgi?id=10700">pidiendo soporte de PulseAudio en xfce4-mixer</a>, la
respuesta del mantenedor es cerrarlo WONTFIX diciendo:</p>
<blockquote>
<p>I'm not telling you that it's a good situation. I'm telling you that
xfce4-mixer is going to get a final 4.12 release and then that it's
unmaintained. This bug won't be fixed.</p>
</blockquote>
<p>Y como alternativa propone usar <a href="https://github.com/andrzej-r/xfce4-pulseaudio-plugin">xfce4-pulseaudio-plugin</a>, que
algunas distros incluyen pero <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=781014">Debian todavía no</a>. El
diálogo es de marzo de este año, así que es posible que no haya habido
tiempo todavía de empaquetarlo.</p>
<p>Así que nos encontramos en una situación en la que las dos aplicaciones
oficiales de Xfce no soportan PulseAudio, y no parece que lo vayan a
tener ya (no al menos hasta que se haga una reescritura completa de las
mismas). Y las alternativas no están maduras o todavía no han llegado a
<em>downstream</em>. Así que es el momento de las soluciones temporales, los
<em>hacks</em> guarros y la cinta adhesiva.</p>
<h2>Pásame la cinta adhesiva, Otilio</h2>
<p>El bug de launchpad <a href="https://bugs.launchpad.net/xfce4-volumed/+bug/883485">"Pulse Audio don't get unmuted when XF86AudioMute
is used"</a> es un compendio de este tipo soluciones/<em>hacks</em> para
el bug del Unmute. La mayoría de ellas se basan en suplantar la
funcionalidad de xfce4-volumed haciendo que el <em>window manager</em> de Xfce
ejecute cierto comando o <em>script</em> cuando se pulsa <em>XF86AudioMute</em> (la
tecla que envía el servidor X cuando se pulsa "Mute" en un teclado con
teclas multimedia). Lo que varía es el comando base utilizado para
controlar la función <em>Mute</em> de PulseAudio.</p>
<p>Por ejemplo, se puede usar el comando <code>pactl</code> para decirle directamente
a PulseAudio que queremos aplicar un Mute o Unmute a un <em>sink</em>. O mejor
todavía, podemos usar "toggle" para cambiar entre Mute y Unmute, que es
lo que realmente suele hacer el botón multimedia:</p>
<div class="highlight"><pre>pactl set-sink-mute <sink> toggle
</pre></div>
<p>El nombre del <em>sink</em> se puede obtener de la lista de <code>pactl list short
sinks</code>.</p>
<p>Basta con añadir este comando a un nuevo atajo de teclado definido en la
la opción de configuración "Teclado" de Xfce:</p>
<p><img alt="Atajo de la tecla Mute a pactl" src="http://www.escomposlinux.org/jcantero/ld/images/xfce-atajo-teclado-mute.png" /></p>
<p><strong>Nota:</strong> es buena práctica reiniciar la sesión para asegurarse que Xfce
ha leído la nueva configuración.</p>
<p>De la misma manera se podría pensar en solucionar el segundo bug
haciendo atajos para que las teclas <em>XF86AudioRaiseVolume</em> y
<em>XF86AudioLowerVolume</em> invoquen el incremento/decremento de volumen en
el <em>sink</em>:</p>
<div class="highlight"><pre>pactl set-sink-volume <sink> +2%
pactl set-sink-volume <sink> "-2%"
</pre></div>
<p>El problema de este método es que sólo sirve para un único <em>sink</em>. Si
hay varios <em>sinks</em>, como mi caso con ALSA y BlueZ (el <em>headset</em>),
necesitaríamos una forma de expresar "el <em>sink</em> que esté ahora activo".
Pero esa forma no existe. Hay un nombre especial (<code>@DEFAULT_SINK@</code>) pero
es para otra cosa distinta: indica el <em>sink</em> por defecto (aquel
seleccionado por el usuario para hacer <em>fallback</em><sup id="fnref:3"><a class="footnote-ref" href="#fn:3" rel="footnote">3</a></sup>). Pero no tenemos
uno equivalente para indicar el <em>sink</em> activo (lo cual es una pena
porque sería realmente útil para el segundo bug).</p>
<p>Ya que un comando no era suficiente, lo siguiente fue escribir <em>scripts</em>
completos que se lanzan al pulsar <em>XF86AudioMute</em>. Por ejemplo hay uno
que parsea la salida de <code>pactl list short sinks</code> para saber cuál está
activo (RUNNING) y aplicarle el <code>pactl set-sink-mute <sink> toggle</code>.
Otro usa un método mucho menos refinado: recorre toda la lista actual de
<em>sinks</em> y aplica el <em>toggle</em> a todos y cada uno de ellos. Algunos
necesitan guardar cierto estado, y lo hacen leyendo y escribiendo el
estado en ficheros entre ejecuciones (¡encima en el directorio
<code>.pulse</code>!).</p>
<p>No puedo ni empezar a describir lo problemático que es todo esto. Son
soluciones superfrágiles, que si bien funcionan para una ñapa rápida, en
cuanto algo se desbarate al que no conozca cómo funcionan le va a dar
unos dolores de cabeza indescriptibles y de muy difícil diagnóstico y
arreglo (más que nada porque no es algo estándar de lo que pueda buscar
una solución o abrir un bug).</p>
<p>En vez de <code>pactl</code> otra gente está usando el comando <code>amixer</code> para hacer
el Mute/Unmute de PulseAudio. Esto funciona porque, aunque amixer es
para manipular el mixer de ALSA, ellos en realidad lo están aplicando
(probablemente sin saberlo) sobre una tarjeta de sonido ALSA virtual
especial llamada "pulse", y que en realidad sirve para representar al
demonio de PulseAudio. Así que cuando ejecutan:</p>
<div class="highlight"><pre>amixer -D pulse set Master mute
amixer -D pulse set Master unmute
amixer -D pulse set Master toggle
</pre></div>
<p>En realidad están diciéndole al mixer de PulseAudio y no al de ALSA que
haga el Mute o Unmute (o el "toggle", que sería el apropiado para
asociar a la tecla <em>XF86AudioMute</em>).</p>
<p>Este engaño no es más que una forma de proporcionar compatibilidad a
viejos programas (normalmente propietarios que no se pueden recompilar
para PulseAudio) que sólo sabían usar tarjetas ALSA a través de
<em>alsa-libs</em>. En el caso de Debian, la magia reside en el paquete
<code>libasound2-plugins</code>, ya que es ahí donde se añade el plugin que crea
esta tarjeta de sonido virtual "pulse" que redirige por detrás el audio
a PulseAudio.</p>
<p>En la página <a href="http://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/PerfectSetup/">The Perfect Setup</a> de PulseAudio, en la sección
"Third Party Applications" (y también en el hilo del bug) se explica
cómo configurar <em>alsa-libs</em> (libasound2) para que la tarjeta de sonido
"pulse" sea el dispositivo por defecto, modificando el
<code>/etc/asound.conf</code> (afecta a todo el sistema) o el <code>~/.asoundr</code> (afecta
sólo al usuario). Resulta que en Debian Jessie y Stretch <strong>no hace
falta</strong>, ya que ya traen esta configuración de serie si se instala el
paquete <code>pulseaudio</code> y su dependencia <code>libasound2-plugins</code>. Por si
alguien tiene curiosidad, está en:
<code>/usr/share/alsa/alsa.conf.d/50-pulseaudio.conf</code> y en
<code>/usr/share/alsa/pulse-alsa.conf</code>.</p>
<p>Lo podemos comprobar con <code>amixer</code>:</p>
<div class="highlight"><pre>$ amixer info
Card default 'pulse'/'PulseAudio'
Mixer name : 'PulseAudio'
Components : ''
Controls : 4
Simple ctrls : 2
</pre></div>
<p>Si lo tenéis así, el <code>-D pulse</code> de los comandos de arriba en realidad
sobra, y el comando de Mute/Unmute se reduce a un simple:</p>
<div class="highlight"><pre>amixer set Master toggle
</pre></div>
<p>Un momento, y entonces ¿por qué falla xfce4-volumed? ¿No es este el
equivalente a lo que hace internamente el demonio? Pues parece ser <a href="http://git.xfce.org/apps/xfce4-volumed/tree/src/xvd_xfconf.c?id=ca667792ad88e2e90e7ae4dac56fe299171aedb7#n181">que
no</a>. En realidad xfce4-volumed no usa el dispositivo ALSA por
defecto sino la propiedad "active-card" de la configuración de
xfce4-mixer que se guarda en el Editor de Configuraciones general de
Xfce:</p>
<p><img alt="Propiedades de xfce4-mixer en el Editor de Configuraciones" src="http://www.escomposlinux.org/jcantero/ld/images/xfce4-mixer-conf-editor.png" /></p>
<p>En mi caso vale <code>HDAIntelPCHAlsamixer</code> y se refiere <strong>específicamente</strong>
al mixer de la tarjeta ALSA física, no al del dispositivo ALSA por
defecto, ya que GStreamer conoce esta tarjeta (a través de su <em>backend</em>
<code>gstreamer0.10-alsa</code>, que la está usando) y por eso se salta la charada
que ha montado PulseAudio para ir a modificar directamente el mixer del
dispositivo ALSA.</p>
<p>Y es aquí donde llegamos a este <a href="https://bugs.freedesktop.org/show_bug.cgi?id=79911#c3">comentario</a> en un bug
abierto contra PulseAudio precisamente por este asunto del Unmute:</p>
<blockquote>
<p>Ok, then I guess xfce4-volumed is accessing alsa directly, instead of
doing the muting through pulseaudio.</p>
<p>Explanation for the inconsistency between muting and unmuting:
xfce4-volumed sets the Master switch to muted. PulseAudio notices that
something happened in the alsa mixer, and sees that one of the switches
is muted, so PulseAudio concludes that the device is muted and sets the
internal device state to mute. While setting the internal state,
pulseaudio also mutes the rest of the switches marked as "switch =
mute", including PCM. When xfce4-volumed unmutes the Master switch,
PulseAudio again notices that something happened, but since the PCM
switch is still muted, PulseAudio concludes that the device is still
muted and does nothing.</p>
<p>xfce4-volumed should be changed to talk to pulseaudio instead of
accessing the alsa mixer directly.</p>
</blockquote>
<p>Esto está en consonancia con lo que ya sabemos (que funciona si usamos
el mixer de PulseAudio) y también explica por qué está pasando (por
culpa de PulseAudio, ¡que raro! <code>:-P</code>). Sólo tenemos que conseguir que
xfce4-volumed use el mixer adecuado para que los problema se arreglen
sin necesidad de andar con atajos de teclado, scripts y demás.</p>
<p>Pues la solución es tan sencilla como instalar el <em>backend</em> de GStreamer
para PulseAudio <code>gstreamer0.10-pulseaudio</code>. Una vez instalado,
nuevamente nos aseguramos que Xfce detecte los cambios <strong>reiniciando la
sesión</strong><sup id="fnref:4"><a class="footnote-ref" href="#fn:4" rel="footnote">4</a></sup>, y en el desplegable de selección de Mixers de xfce4-mixer
elegimos como dispositivo el que corresponde a "PulseAudio Mixer" en vez
del "ALSA Mixer".</p>
<p><img alt="Seleccionando el Mixer de PulseAudio en xfce4-mixer" src="http://www.escomposlinux.org/jcantero/ld/images/xfce4-mixer-pulseaudio-choice.png" /></p>
<p>¡Y funciona! Bueno, funciona el Mute/Unmute correctamente, pero sólo
para el dispositivo ALSA. También he conseguido que se arregle el tercer
bug (ya no tengo notificaciones de cambios de sonido fantasmas). Puedo
cambiar el Mixer al que corresponde a mi <em>headset</em> si lo enciendo antes
de iniciar la sesión (entonces las teclas de Mute y de volumen
funcionan, pero sólo para el <em>headset</em>), pero no es práctico tener que
reiniciar la sesión cada vez que quiero cambiar de dispositivo
PulseAudio. Como ya he comentado, esto sólo se soluciona con una
aproximación más dinámica a la detección de dispositivos y eso es algo
de lo que carecen actualmente tanto xfce4-mixer como xfce4-volumed.</p>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>El escritorio que uso actualmente. <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>Únicamente lo he visto empaquetado en el AUR de Arch Linux. <a class="footnote-backref" href="#fnref:2" rev="footnote" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:3">
<p>Es el que se usa cuando el <em>sink</em> recordado por PulseAudio para
la aplicación actual no está presente. <a class="footnote-backref" href="#fnref:3" rev="footnote" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
<li id="fn:4">
<p>Si no xfce4-mixer empezará a hacer cosas raras como no dejarnos
seleccionar el Mixer de PulseAudio. <a class="footnote-backref" href="#fnref:4" rev="footnote" title="Jump back to footnote 4 in the text">↩</a></p>
</li>
</ol>
</div>FFmpeg volverá a Debian2015-07-08T15:57:00+02:00Javier Canterotag:www.escomposlinux.org,2015-07-08:jcantero/ld/2015/07/08/ffmpeg-volvera-a-debian/<p><a href="https://ffmpeg.org/">FFmpeg</a> volverá definitivamente a Debian (Stretch) en
detrimento de su <em>fork</em> libav. Esa es la <a href="https://lists.debian.org/debian-devel-announce/2015/07/msg00001.html">decisión final</a>
que ha tomado el equipo de mantenedores de Debian Multimedia:</p>
<blockquote>
<p>After a careful review of all the pros and cons we, the Debian
Multimedia Maintainers team, have finally decided to switch from
Libav to FFmpeg as provider for the libav* multimedia libraries.
We'll try our best to make this happen in time for stretch.</p>
</blockquote>
<p>Esperemos que con esto se cierre definitivamente una de las más agrias
polémicas dentro y fuera de la comunidad Debian.</p>
<p>:wq</p>Exaile migrará a GStreamer 1.x2015-07-06T19:30:00+02:00Javier Canterotag:www.escomposlinux.org,2015-07-06:jcantero/ld/2015/07/06/exaile-migrara-a-gstreamer-1x/<p>Pues resulta que exaile <a href="http://www.exaile.org/2015/05/18/Exaile-upgrade-gstreamer-gtk/">ya había anunciado planes para migrar a
GStreamer 1.x</a> (y a GTK3) en cuanto se anunció que se
<a href="http://www.escomposlinux.org/jcantero/ld/2015/07/06/borrado-de-gstreamer-010-para-debian-stretch/">descontinuaban los paquetes de GStreamer 0.10 en
Debian</a>.</p>
<p>Hasta ahora no habían tenido <a href="http://www.escomposlinux.org/jcantero/ld/2013/11/06/actualizacion-de-exaile/">mucha prisa</a>, pero parece
que ahora no les queda más remedio se han puesto a trabajar a destajo:</p>
<blockquote>
<p>Due to the amount of work required, we’re suspending work on
non-critical bugs on the 3.4.x series until we’ve merged this into
master.</p>
</blockquote>
<p>Si queréis saber cómo va la transición el wiki de exaile tiene una
<a href="https://github.com/exaile/exaile/wiki/PyGI-migration-tasklist-%28GTK3-GStreamer-1.x%29">sección dedicada</a>. También decir que el equipo de
exaile recluta voluntarios tanto para las tareas de programación como de
test y <em>debugging</em> de la <a href="https://github.com/exaile/exaile/tree/gi">nueva versión</a>.</p>
<p>:wq</p>Borrado de GStreamer 0.10 para Debian Stretch2015-07-06T19:05:00+02:00Javier Canterotag:www.escomposlinux.org,2015-07-06:jcantero/ld/2015/07/06/borrado-de-gstreamer-010-para-debian-stretch/<p>Acabo de <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=785198">descubrir</a> que los mantenedores de
GStreamer en Debian se ha marcado como objetivo para Stretch la
eliminación de la versión 0.10:</p>
<blockquote>
<p>GStreamer 0.10 is no longer maintained and supported by the upstream
project since almost 3 years now, and contains many known bugs that
are fixed in the new 1.x release series of GStreamer. Next to many
bug fixes, the new release series also contains many other
improvements, new features and a more streamlined API.</p>
</blockquote>
<p>Ya hablé hace 2 años en <a href="http://www.escomposlinux.org/jcantero/ld/2013/11/20/la-situacion-gstreamer/">La situación GStreamer</a> del lío
que tenían montado por mantener las dos versiones. Por un lado, hay que
decir que ya era hora. Pero por otro, habrá que ver qué pasa con las
aplicaciones que todavía dependen de GStreamer 0.10. En mi caso, exaile,
workrave y los componentes xfce4-mixer y xfce4-volumed de Xfce todavía
dependen de esta versión.</p>
<p>:wq</p>Headset Bluetooth en Debian Jessie (y Stretch)2015-07-03T19:32:00+02:00Javier Canterotag:www.escomposlinux.org,2015-07-03:jcantero/ld/2015/07/03/headset-bluetooth-en-debian-jessie-y-stretch/<p>Echar a andar un <em>headset</em><sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup> Bluetooth es uno de los mayores dolores
de cabeza que se pueden encontrar actualmente en una distribución Linux,
como queda demostrado si se echa un vistazo a la cantidad de mensajes en
foros solicitando ayuda o al tamaño de la <a href="https://wiki.archlinux.org/index.php/Bluetooth_headset">sección dedicada a ello del
wiki de Arch Linux</a><sup id="fnref:2"><a class="footnote-ref" href="#fn:2" rel="footnote">2</a></sup>. Y ahora yo también puedo decirlo
de primera mano ya que lo he sufrido en mis carnes.</p>
<p>Hay que decir que el soporte de Bluetooth en Linux siempre ha sido un
poco "magia negra". Si hace poco <a href="http://www.escomposlinux.org/jcantero/ld/2015/05/27/instalando-pulseaudio-en-debian-jessie/">me quejaba de la escasa documentación
de PulseAudio</a>, el caso de la pila de Bluetooth es mucho
peor si cabe. Y para ahondar aún más en el problema, una buena parte de
poca información que hay por ahí ha quedado desfasada, como le pasa a la
<a href="https://wiki.debian.org/BluetoothUser">página del wiki de Debian sobre Bluetooth</a>.</p>
<p>Así que, para contar esta historia tengo que empezar explicando que el
soporte de Bluetooth en Linux se compone de dos partes:</p>
<ul>
<li>
<p>espacio kernel: en los fuentes del kernel se implementan los drivers
de acceso al hardware (a los diferentes <em>chipsets</em> como los de
Broadcom o Atheros) y también algunos protocolos de bajo nivel. El
kernel exporta una serie de dispositivos <code>hci0</code>, <code>hci1</code>, <code>hci2</code>, ...
muy parecidos a los dispositivos <code>eth0</code>, <code>eth1</code>, ... que exportan los
dispositivos de red.</p>
</li>
<li>
<p>espacio de usuario: el resto de los protocolos de alto nivel, así
como las herramientas de configuración y demás las implementa
<a href="http://www.bluez.org/">BlueZ</a>.</p>
</li>
</ul>
<p>No voy a contar aquí cómo funciona Bluetooth (para eso está la
<a href="https://en.wikipedia.org/wiki/Bluetooth">Wikipedia</a>), pero sí que haré un símil para que se
entienda fácilmente. Así como la pila de red está formada por un montón
de protocolos, desde protocolos de nivel 1 y 2 que se implementan
normalmente en el propio hardware —la tarjeta de red— hasta protocolos
de alto nivel como SMTP, HTTP y demás, Bluetooth también está formado
por una serie de protocolos unos encima de otros. Al fin y al cabo,
Bluetooth no es más que otro tipo de red, sólo que una especialmente
diseñada para distancias cortas, y donde el consumo energético es una
importante restricción.</p>
<p>En Bluetooth hay una serie de protocolos de bajo nivel —que no nos
interesan en esta descripción— y luego están el equivalente a los
protocolos de alto nivel —a los SMTP y HTTP de la pila de red— que en
Bluetooth se llaman <em>perfiles</em> (profiles), y que son los que permiten
que un dispositivo funcione para una tarea u otra. En este artículo
mencionaré perfiles como <a href="https://en.wikipedia.org/wiki/List_of_Bluetooth_profiles#Advanced_Audio_Distribution_Profile_.28A2DP.29">A2DP</a> o <a href="https://en.wikipedia.org/wiki/List_of_Bluetooth_profiles#Headset_Profile_.28HSP.29">HSP</a>, ambos relacionados
con el audio (que es lo que nos incumbe aquí), pero hay <a href="https://en.wikipedia.org/wiki/List_of_Bluetooth_profiles">muchos
otros</a>. También quiero señalar que cuando un dispositivo
Bluetooth es algo simple como unos cascos o un ratón, estos protocolos
se implementan en hardware o firmware, por lo que no son actualizables
y en concreto los perfiles estarán limitados a lo que venga de fábrica.</p>
<p>En cambio cuando tenemos un aparato complejo, como un ordenador o un
<em>smartphone</em>, uno se puede permitir implementar una parte de la pila de
Bluetooth en software en vez de en hardware, y esta parte normalmente
son los perfiles (o sea, los protocolos de alto nivel). Esa es la parte
de la que esencialmente se encarga BlueZ, por sí mismo o con ayuda de
otras partes del sistema operativo.</p>
<p>En el caso de unos auriculares o un micrófono Bluetooth —o ambos como
es el caso de un <em>headset</em>— BlueZ colabora con el subsistema de sonido
(ALSA, PulseAudio, ...) para traernos audio hasta nuestras orejas (o
llevar nuestra voz).</p>
<h2>Bluez 5 y PulseAudio 5.0 y 6.0</h2>
<p>Cuando <a href="http://www.bluez.org/release-of-bluez-5-0/">en Navidades de 2012 salió BlueZ 5</a> se
produjeron un par de cambios relevantes en este software. El primero fue
que <a href="http://git.kernel.org/cgit/bluetooth/bluez.git/commit/?id=4ff9b99292eca193dc0c149722328cb0b1ab0818">BlueZ 5 eliminó el soporte para ALSA</a> y empezó a
utilizar exclusivamente PulseAudio como subsistema al que derivar las
tareas de audio. Los usuarios de BlueZ que hasta ese momento habían
usado ALSA no tenían más remedio que migrar a PulseAudio o quedarse
anclados en BlueZ 4. Por otro lado, en BlueZ 5 los perfiles HSP (para
<em>headsets</em>) y HFP (para manos libres telefónicos), que hasta ese momento
se <a href="http://www.bluez.org/release-of-bluez-5-0/">implementaban internamente fueron eliminados</a> en
favor de una implementación externa (concretamente por el demonio de
PulseAudio uno y el software telefónico oFono el otro):</p>
<blockquote>
<p>Remove internal support for telephony (HFP and HSP) profiles. They
should be implemented using the new Profile interface preferably by
the telephony subsystem of choice (e.g. oFono which already supports
this)</p>
</blockquote>
<p>Por si fueran pocos cambios, BlueZ 5 introdujo el uso de una nueva
herramienta de configuración, <code>bluetoothctl</code>, en vez de la variada
colección que había que usar en las versiones previas. Toda la
documentación que había hasta el momento en foros y wikis para
configurar BlueZ quedó obsoleta de un plumazo<sup id="fnref:3"><a class="footnote-ref" href="#fn:3" rel="footnote">3</a></sup>. Es lo que le pasa a
la mencionada página de Debian, por ejemplo.</p>
<p>Al mover BlueZ parte de su funcionalidad a PulseAudio, había que
actualizar también éste. Pero hasta Marzo de 2014 no aparece la primera
versión de PulseAudio con soporte para BlueZ 5, la 5.0, <a href="http://www.freedesktop.org/wiki/Software/PulseAudio/Notes/5.0/">que sólo trae
soporte para el perfil A2DP</a>:</p>
<blockquote>
<p>PulseAudio now supports BlueZ 5, but only the A2DP profile, which
means that in case of headsets, only playback is available, the
headset microphone can't be used. BlueZ 4 is still the only way to
make the headset and hands-free profiles work.</p>
</blockquote>
<p>No es hasta <a href="http://freedesktop.org/wiki/Software/PulseAudio/Notes/6.0/">PulseAudio 6.0</a> aparecida en Febrero de 2015
que no se añade soporte para los perfiles HSP y HFP (y éste último
exclusivamente mediante oFono). Esto significa que si usas la
combinación BlueZ 5 junto con PulseAudio 5.0 sólo tienes soporte para la
parte de auriculares de tu <em>headset</em> y no para el micrófono, mientras
que si usas BlueZ 5 junto con PulseAudio 6.0 tienes —o deberías tener—
soporte para ambos.</p>
<p>Me diréis que no tiene sentido usar PulseAudio 5.0 teniendo la versión
6.0 disponible, pero es que Debian Jessie lleva PulseAudio 5.0, ya que
cuando apareció la versión 6.0 de PulseAudio la distribución estaba en
<a href="http://www.escomposlinux.org/jcantero/ld/2015/01/05/debian-jessie-como-va-el-freeze-3/">un estado de <em>freeze</em> profundo</a> y ya no se podía actualizar
el paquete. Debian Stretch, la actual <em>testing</em>, sí que lleva PulseAudio
6.0, aunque ya veremos que eso no significa que se terminen los
problemas.</p>
<h2>Configurando el kernel para Bluetooth</h2>
<p>Ahora que ya hemos visto el panorama general es hora que pasemos a la
parte práctica y a los detalles sucios. Para los que no se quieren
manchar las manos hay asistentes gráficos tipo Blueman o Bluedevil,
aunque ya os adelanto que si hay problemas no os van a servir para
solucionarlos si no entendéis lo que está pasando por debajo.</p>
<p>Lo primero que tuve que hacer en mi caso es compilar un kernel con
soporte para Bluetooth. Los que uséis los kernels estándar de vuestra
distribución es de suponer que ya vienen con todo compilado, incluso con
aquello que nunca usaréis.</p>
<p><img alt="Menú de Bluetooth de KConfig" src="http://www.escomposlinux.org/jcantero/ld/images/bluetooth-kernel-options.png" /></p>
<p>El soporte para BNEP es para hacer <em>tethering</em>, así que no lo he
incluído. El HIDP sí, por si alguna vez uso un teclado o ratón Bluetooth
(en realidad es para enlazar con la parte de dispositivos de entrada
HID). Le he puesto además soporte para LE porque mi <em>dongle</em> soporta
Bluetooth 4.0.</p>
<p>La opción <code>Bluetooth device drivers</code> da acceso al submenú donde escoger
qué drivers (módulos) incluir:</p>
<p><img alt="Menú de Bluetooth device drivers de KConfig" src="http://www.escomposlinux.org/jcantero/ld/images/bluetooth-kernel-options-2.png" /></p>
<p>Los <em>dongles</em> USB para equipos de sobremesa y los integrados en los
laptops suelen utilizar el módulo <code>btusb</code>, que es el <code>HCI USB driver</code> en
este caso, pero algunos portátiles usan otros módulos dependiendo el
hardware que lleven. En mi caso comprobé qué hardware tenía, y si tenía
soporte, consultando los datos USB del <em>dongle</em>:</p>
<div class="highlight"><pre>$ lsusb
...
Bus 003 Device 001: ID 0a5c:21e8 Broadcom Corp. BCM20702A0 Bluetooth 4.0
...
</pre></div>
<p>Con el VendorID:ProdID (0a5c:21e8) me fue fácil encontrar que se había
añadido <a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=6dfc326f0605fd87e4c10ccde10de0ce4280d72d">soporte para este dispositivo</a> en el módulo de
<code>btusb</code> desde el <a href="https://github.com/torvalds/linux/commit/6dfc326f0605fd87e4c10ccde10de0ce4280d72d">kernel 3.4</a> <sup id="fnref:4"><a class="footnote-ref" href="#fn:4" rel="footnote">4</a></sup>. Pero resulta que en
mi fichero <code>drivers/bluetooth/btusb.c</code> del kernel 4.0.5 no encontraba
los números en cuestión. No fue hasta que encontré este
<a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=92c385f46b30f4954e9dd2d2005c12d233b479ea">commit</a> (<a href="https://github.com/torvalds/linux/commit/92c385f46b30f4954e9dd2d2005c12d233b479ea">github</a>) que me dí cuenta
de lo que había pasado: para no tener que añadir cada ProdID nuevo a la
tabla de identificadores a partir de ese cambio todos los dispositivos
Broadcom (VendorID=0a5c) se tratan como uno solo.</p>
<p>El nuevo kernel con el soporte de Bluetooth compilado y el driver btusb
se veía así en <code>dmsg</code> tras arrancar el sistema operativo:</p>
<div class="highlight"><pre>[ 39.005283] Bluetooth: Core ver 2.20
[ 39.005293] NET: Registered protocol family 31
[ 39.005295] Bluetooth: HCI device and connection manager initialized
[ 39.005297] Bluetooth: HCI socket layer initialized
[ 39.005299] Bluetooth: L2CAP socket layer initialized
[ 39.005303] Bluetooth: SCO socket layer initialized
</pre></div>
<p>Y enchufando el USB <em>dongle</em>:</p>
<div class="highlight"><pre>[ 2996.695737] usb 3-1: new full-speed USB device number 2 using xhci_hcd
[ 2996.826020] usb 3-1: New USB device found, idVendor=0a5c, idProduct=21e8
[ 2996.826026] usb 3-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 2996.826029] usb 3-1: Product: BCM20702A0
[ 2996.826031] usb 3-1: Manufacturer: Broadcom Corp
[ 2996.826033] usb 3-1: SerialNumber: ------------
[ 2996.869091] usbcore: registered new interface driver btusb
[ 2996.869309] bluetooth hci0: Direct firmware load for brcm/BCM20702A0-0a5c-21e8.hcd failed with error -2
[ 2996.869313] Bluetooth: hci0: BCM: patch brcm/BCM20702A0-0a5c-21e8.hcd not found
</pre></div>
<p>Las dos últimas líneas me preocupaban, así que estuve investigando y
llegué al siguiente commit <a href="https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=10d4c6736ea6e6ff293dd588551270bca00ca45d">"btusb: Add Broadcom patch RAM
support"</a> (<a href="https://github.com/torvalds/linux/commit/10d4c6736ea6e6ff293dd588551270bca00ca45d">github</a>):</p>
<blockquote>
<p>After hardware reset, some BCM Bluetooth adapters obtain their
initial firmware from OTPROM chip. Once this initial firmware is
running, the firmware can be further upgraded over HCI interface with
.hcd files provided by Broadcom. This is also known as "patch RAM"
support. This change implements that.</p>
<p>If the .hcd file is not found in /lib/firmware, BCM Bluetooth adapter
continues to operate with the initial firmware.</p>
</blockquote>
<p>Antes he dicho que los dispositivos de capacidad reducida (como es el
caso de este <em>dongle</em>) tienden a implementar Bluetooth en hardware o
firmware, por lo que luego no se pueden actualizar. Parece que Broadcom
ha intentado superar esta limitación haciendo que el driver que lo
controla le mande al dispositivo una versión más moderna del firmware
cuando lo inicializa. Esos firmwares más modernos son proporcionados por
el fabricante en forma de ficheros (en el caso de Broadcom con extensión
<code>.hcd</code>) para que el driver los lea y envíe.</p>
<p>El fichero de firmware que buscaba el driver para mi hardware
(<code>brcm/BCM20702A0-0a5c-21e8.hcd</code>) no aparecía ni en el paquete
<a href="https://packages.debian.org/jessie/firmware-linux-free">firmware-linux-free</a> (esperable dada la actitud
de Broadcom hacia el software libre) ni en el más general <a href="http://git.kernel.org/cgit/linux/kernel/git/firmware/linux-firmware.git/tree/">repositorio
git de firmwares en kernel.org</a> (menos esperable) que
contiene firmwares no libres pero sí con permiso de distribución.
Tampoco aparecía ninguna referencia a drivers para Linux en el CD que
viene con el <em>dongle</em>.</p>
<p>Lo que era más preocupante: buscando por ese nombre de fichero en la
Web, encontré <a href="http://plugable.com/2014/06/23/plugable-usb-bluetooth-adapter-solving-hfphsp-profile-issues-on-linux">que se necesitaba el firmware de marras para hacer
funcionar los perfiles HSP y HFP</a>. Pero como en ese momento
estaba en Debian Jessie con PulseAudio 5.0 (que ya he dicho que carece
de soporte para estos perfiles) me dije que de momento podía probar a
ver si funcionaba sin el fichero de firmware. Aunque este otro
<a href="http://www.spinics.net/lists/linux-bluetooth/msg47875.html">comentario</a> en la lista de correo de linux-bluetooth:</p>
<blockquote>
<p>Anyhow, one minor thing that bugs me is this:</p>
<p>[193452.790194] Bluetooth: hci0: BCM: patch brcm/BCM20702A0-0a5c-21e8.hcd not found</p>
<p>While I want the firmware loading available for all Broadcom
controllers, I do think we might have to mark some of them as firmware
absolutely required since otherwise they will not work. And in that case
we should print the error. Otherwise we might just silently not print
anything. Thoughts?</p>
</blockquote>
<p>parecía dar a entender que en el caso de mi <em>dongle</em> el firmware era
imprescindible para que funcionara correctamente. De hecho, lo que en
ese hilo se sugiere es implementar que, en los casos en que se sabe
positivamente que el firmware es necesario, si no se encuentra el
fichero correspondiente el driver emita un error y no inicialice el
dispositivo. Pero desde que se había escrito ese mensaje (8 de mayo de
2014) no se había hecho nada en esa línea, y el driver seguía
simplemente emitiendo un aviso cuando no encontraba el fichero de
firmware (como en mi caso).</p>
<p>A pesar de los malos augurios, me lancé primero a intentar hacer
funcionar el <em>headset</em> sin firmwares binarios propietarios opacos.</p>
<h2>Configurando Bluetooth en el espacio de usuario</h2>
<p>Tener el kernel con el driver cargado es sólo la mitad del trabajo.
Ahora es cuando BlueZ, la parte de espacio de usuario, entra en escena.
Lo primero es instalarlo, e instalar también el módulo de integración
con PulseAudio:</p>
<div class="highlight"><pre># aptitude install bluez pulseaudio-module-bluetooth
Se instalarán los siguiente paquetes NUEVOS:
bluez libsbc1{a} pulseaudio-module-bluetooth
</pre></div>
<p>La versión de BlueZ que lleva Debian Jessie es la 5.23, que es la misma
que de momento lleva Stretch, aunque en el instante que escribo esto la
versión más reciente de <em>upstream</em> es la 5.31.</p>
<p>La parte fundamental de BlueZ es <code>bluetoothd</code>, un demonio del sistema
que es el que se encarga de gestionar los interfaces Bluetooth
existentes, y de hablar con los dispositivos que se pongan dentro de su
alcance para presentarlos a otros servicios según qué perfiles
soporten<sup id="fnref:5"><a class="footnote-ref" href="#fn:5" rel="footnote">5</a></sup>. Por ejemplo, en mi caso quiero que si un dispositivo
Bluetooth —mi <em>headset</em>— entra en el alcance de mi <em>dongle</em>,
<code>bluetoothd</code> interrogue al <em>headset</em> para descubrir que soporta los
perfiles A2DP y/o HSP, y a partir de ello informe a PulseAudio que hay
disponibles dos nuevos dispositivos: los auriculares a los que enviar
audio y el micrófono del que recibirlo.</p>
<p>Por lo tanto es obvio que si queremos que los dispositivos Bluetooth
funcionen, debemos asegurarnos que <code>bluetoothd</code> esté ejecutándose de
contínuo. En Debian, el demonio lo tiene que haber arrancado el sistema
de init que uséis (System V o systemd), y el servicio debe estar en
marcha. Por ejemplo, en systemd:</p>
<div class="highlight"><pre># systemctl status bluetooth.service
● bluetooth.service - Bluetooth service
Loaded: loaded (/lib/systemd/system/bluetooth.service; enabled)
Active: active (running) since mar 2015-05-30 18:43:12 CEST; 36min ago
Docs: man:bluetoothd(8)
Main PID: 3731 (bluetoothd)
Status: "Running"
CGroup: /system.slice/bluetooth.service
└─3731 /usr/lib/bluetooth/bluetoothd
may 30 18:43:12 ******** bluetoothd[3731]: Bluetooth daemon 5.23
may 30 18:43:12 ******** bluetoothd[3731]: Starting SDP server
may 30 18:43:12 ******** bluetoothd[3731]: kernel lacks bnep-protocol support
may 30 18:43:12 ******** bluetoothd[3731]: System does not support network plugin
may 30 18:43:12 ******** bluetoothd[3731]: Failed to open RFKILL control device
may 30 18:43:12 ******** bluetoothd[3731]: Bluetooth management interface 1.9 initialized
</pre></div>
<p>Si usáis System V init los mensajes de log estarán en <code>/var/log/daemon.log</code>.
Dos aclaraciones con respecto a lo que pueden parecer errores:</p>
<ol>
<li>Recordad que quité el soporte de BNEP de la configuración de mi
kernel (por eso tampoco tengo soporte del plugin de network)</li>
<li>Un <em>dongle</em> enchufado a un USB evidentemente no tiene botones para
encender/apagar el Bluetooth como existen en los portátiles. Por eso no
hay un dispositivo RFKILL que abrir (vamos, que no es un error).</li>
</ol>
<p>Es hora de conectar el <em>dongle</em> a un puerto USB y ver qué pasa:</p>
<div class="highlight"><pre>bluetoothd[3731]: Sap driver initialization failed.
bluetoothd[3731]: sap-server: Operation not permitted (1)
</pre></div>
<p>Olvidad de momento estos errores que aparecen en los logs (más adelante
explicaré por qué aparecen y cómo quitarlos) y centrémonos en ver si el
dispositivo Bluetooth está en marcha. Para ello usaremos una herramienta
de bajo nivel de las que vienen con BlueZ: <code>hciconfig</code>. Esta herramienta
es el equivalente a <code>ifconfig</code> pero para dispositivos <a href="https://en.wikipedia.org/wiki/List_of_Bluetooth_protocols#HCI">HCI</a>
Bluetooth:</p>
<div class="highlight"><pre>$ hciconfig
hci0: Type: BR/EDR Bus: USB
BD Address: XX:XX:XX:XX:XX:XX ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING
RX bytes:1504 acl:0 sco:0 events:180 errors:0
TX bytes:29730 acl:0 sco:0 commands:179 errors:0
</pre></div>
<p>Como podéis observar, ahora tengo un dispositivo <code>hci0</code>, así que el
<em>dongle</em> ha sido reconocido por el kernel y está funcionando. El
<em>dongle</em> tiene una dirección de red única similar a la de las tarjetas
de red Ethernet<sup id="fnref:6"><a class="footnote-ref" href="#fn:6" rel="footnote">6</a></sup> que yo he preferido ocultar, por lo que aparece como
XX:XX:XX:XX:XX:XX.</p>
<p>Aunque hemos usado <code>hciconfig</code> para ver que el dispositivo está ahí, no
lo vamos a emplear para configurarlo como se hacía antiguamente. En
BlueZ 5 es el demonio <code>bluetoothd</code> el que controla los dispositivos HCI
(<code>hci0</code>, <code>hci1</code>, etc). Los usuarios le dan órdenes a <code>bluetoothd</code>
mediante la herramienta <code>bluetoothctl</code> y éste hace lo que haga falta con
el dispositivo en cuestión, almacenando el estado si fuera necesario:</p>
<div class="highlight"><pre>$ bluetoothctl
[NEW] Controller XX:XX:XX:XX:XX:XX ******** [default]
[bluetooth]#
</pre></div>
<p>El <em>prompt</em> de <code>bluetoothctl</code> está esperando comandos que pasarle a
<code>bluetoothd</code>. <code>help</code> os dará una lista de los comandos disponibles. Por
ejemplo, si <code>hciconfig</code> hubiera mostrado el dispositivo como DOWN en vez
de UP RUNNING, podríamos ordenar levantarlo con un <code>power on</code>. En mi
caso ya está levantado, así que no es necesario a pesar de lo que <a href="https://wiki.archlinux.org/index.php/Bluetooth_headset">diga
el Arch Wiki</a>. Los siguientes comandos de esa lista en
cambio sí son necesarios, aunque es suficiente con ejecutarlos una única
vez (la primera), ya que <code>bluetoothd</code> guarda su estado y los recordará:</p>
<div class="highlight"><pre>[bluetooth]# agent on
Agent registered
[bluetooth]# default-agent
Default agent request successful
</pre></div>
<p>Ahora el <em>dongle</em> está listo, pero todavía no está buscando activamente
a otros dispositivos Bluetooth que pueda haber en su radio de alcance.
Estar activo significa gastar energía, y en Bluetooth el ahorro de
energía es una prioridad. Así que debemos decirle explícitamente al
dispositivo HCI que active la búsqueda de otros dispositivos Bluetooth:</p>
<div class="highlight"><pre>bluetooth]# scan on
Discovery started
[CHG] Controller XX:XX:XX:XX:XX:XX Discovering: yes
[bluetooth]#
</pre></div>
<p>En este momento enciendo el <em>headset</em> y espero hasta que me reconoce el
nuevo dispositivo a través de la conexión Bluetooth (paciencia, le
cuesta un poco). Cuando aparece:</p>
<div class="highlight"><pre>[NEW] Device YY:YY:YY:YY:YY:YY Energy BT5+
[bluetooth]#
</pre></div>
<p>es que el <em>dongle</em> ha encontrado un nuevo dispositivo —el <em>headset</em>—, y
además nos dice la dirección de red de éste (que yo he ocultado bajo
YY:YY:YY:YY:YY:YY).</p>
<p>Por motivos de seguridad, no es buena idea permitir que cualquier
dispositivo sin identificar establezca una conexión sin más con nuestro
sistema. Imaginaos el cachondeo que sería que cualquiera con un teclado
Bluetooth pudiera conectarlo a nuestro ordenador desde la habitación de
al lado y teclear lo que le diera la gana como si fuéramos nosotros<sup id="fnref:7"><a class="footnote-ref" href="#fn:7" rel="footnote">7</a></sup>.
El usuario tiene de alguna forma que dar el visto bueno al dispositivo
remoto que se quiere conectar, y esto se hace mediante el <em>emparejado</em>
(pair) de los dos dispositivos:</p>
<div class="highlight"><pre>[bluetooth]# pair YY:YY:YY:YY:YY:YY
Attempting to pair with YY:YY:YY:YY:YY:YY
[CHG] Device YY:YY:YY:YY:YY:YY Connected: yes
[CHG] Device YY:YY:YY:YY:YY:YY UUIDs:
00001108-0000-1000-8000-00805f9b34fb
0000110b-0000-1000-8000-00805f9b34fb
0000110c-0000-1000-8000-00805f9b34fb
0000110e-0000-1000-8000-00805f9b34fb
0000111e-0000-1000-8000-00805f9b34fb
00001200-0000-1000-8000-00805f9b34fb
[CHG] Device YY:YY:YY:YY:YY:YY Paired: yes
Pairing successful
[CHG] Device YY:YY:YY:YY:YY:YY Connected: no
</pre></div>
<p>El emparejado ha funcionado, aunque luego el dispositivo se ha
desconectado (puede ser simplemente por el ahorro de energía).</p>
<p>Como no queremos estar emparejando manualmente el <em>headset</em> cada vez que
lo encendamos, le vamos a indicar a <code>bluetoothd</code> que en adelante cuando
vuelva a encontrar al dispositivo YY:YY:YY:YY:YY:YY se fíe de él y haga
el <em>pair</em> automáticamente sin que nosotros le digamos nada. Esto se
consigue mediante el comando <code>trust</code>:</p>
<div class="highlight"><pre>bluetooth]# trust YY:YY:YY:YY:YY:YY
[CHG] Device YY:YY:YY:YY:YY:YY Trusted: yes
Changing YY:YY:YY:YY:YY:YY trust succeeded
</pre></div>
<p>Estoy diciendo que <code>bluetoothd</code> guarda toda esta información, pero es
mejor que lo veáis por vosotros mismos: está en <code>/var/lib/bluetooth/</code>
(acceso como <em>root</em>). Por cierto, si por cualquier causa queréis purgar
el paquete <code>bluez</code> para empezar desde cero, tendréis que borrar
manualmente el contenido de ese directorio porque el paquete Debian no
lo hace cuando se desinstala (Bug <a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=511608">#511608</a>).</p>
<p>Ahora es cuando finalmente conectamos con el <em>headset</em>:</p>
<div class="highlight"><pre>[bluetooth]# connect YY:YY:YY:YY:YY:YY
Attempting to connect to YY:YY:YY:YY:YY:YY
Failed to connect: org.bluez.Error.Failed
</pre></div>
<p>¡¡Error!! Tranquilos, está todo bajo control. Quería mostraros el que
creo que es el punto en el que mucha gente se atasca. Veamos lo que
dicen los logs:</p>
<div class="highlight"><pre>may 30 19:32:04 ******** bluetoothd[3731]: a2dp-sink profile connect failed for YY:YY:YY:YY:YY:YY: Protocol not available
</pre></div>
<p>Lo de "a2dp-sink" es una buena pista de la causa del problema. ¿Os
acordáis que cuando instalé el paquete <code>bluez</code> instalé también
<code>pulseaudio-module-bluetooth</code>? Pues lo que pasa es que el módulo en
cuestión no está cargado en el proceso de PulseAudio que <strong>ya</strong> está
lanzado. Podríamos parar y reiniciar el servicio para que lea la nueva
configuración, pero me cuesta menos decirle a PulseAudio que cargue el
módulo:</p>
<div class="highlight"><pre>$ pactl load-module module-bluetooth-discover
20
$ pactl list short modules | grep bluetooth
20 module-bluetooth-discover
</pre></div>
<p>¿Alguién más piensa como yo que el paquete
<code>pulseaudio-module-bluetooth</code> debería encargarse de ello
automáticamente si el servicio PulseAudio está ya en marcha?</p>
<p>Volviendo a los logs, ahora muestran una cosa bien distinta:</p>
<div class="highlight"><pre>may 30 19:41:29 ******** bluetoothd[3731]: Endpoint registered: sender=:1.42 path=/MediaEndpoint/A2DPSource
may 30 19:41:29 ******** bluetoothd[3731]: Endpoint registered: sender=:1.42 path=/MediaEndpoint/A2DPSink
</pre></div>
<p>El demonio <code>bluetoothd</code> ha sido capaz de registrar dos objetos
<a href="https://en.wikipedia.org/wiki/D-Bus">D-Bus</a>, uno para los auriculares del <em>headset</em>
(<code>/MediaEndpoint/A2DPSink</code>) y otro para el micrófono
(<code>/MediaEndpoint/A2DPSource</code>), que son los que empleará PulseAudio para
enviar/recibir audio. Esto sucede en cuanto se enchufa el <em>dongle</em>, no
hace falta que esté encendido el <em>headset</em> o cualquier otro dispositivo
con perfiles A2DP y/o HSP.</p>
<p>Si encendemos ahora el <em>headset</em> y entramos en <code>bluetoothctl</code> veremos
que <code>bluetoothd</code> ha establecido automáticamente la conexión sin que le
hayamos tenido que decir nada (si no fuera así, ejecutad el comando
<code>connect YY:YY:YY:YY:YY:YY</code> manualmente, ahora no debería dar error;
también puede ser un buen momento para parar el scan con un <code>scan off</code>
si no tenemos más dispositivos que emparejar). Y en los logs aparece:</p>
<div class="highlight"><pre>may 30 19:44:41 ******** bluetoothd[3731]: /org/bluez/hci0/dev_YY_YY_YY_YY_YY_YY/fd0: fd(18) ready
may 30 19:44:41 ******** bluetoothd[3731]: Can't open input device: No such file or directory (2)
may 30 19:44:41 ******** bluetoothd[3731]: AVRCP: failed to init uinput for YY:YY:YY:YY:YY:YY
</pre></div>
<p>La primera línea (otro objeto exportado a través de D-Bus) nos confirma
que la conexión con el <em>pair</em> remoto se ha establecido. Para las otras
dos líneas de error he encontrado una solución en el <a href="https://wiki.gentoo.org/wiki/Bluetooth_Headset#Can.27t_open_input_device">wiki de
Gentoo</a>: compilar el kernel con estas opciones:</p>
<div class="highlight"><pre>Device Drivers --->
Input device support --->
[*] Miscellaneous devices --->
<M> User level driver support
</pre></div>
<p><code>/dev/uinput</code> es un driver para <a href="http://thiemonge.org/getting-started-with-uinput">crear dispositivos de entrada virtuales en
<code>/dev/input/</code> desde espacio de usuario</a>. <code>bluetoothd</code> crea un nuevo
dispositivo de entrada <code>/dev/input/eventN</code> (siendo N un número correlativo)
cuando enciendo el <em>headset</em>, y en los logs del kernel aparece:</p>
<div class="highlight"><pre>input: YY:YY:YY:YY:YY:YY as /devices/virtual/input/input17
</pre></div>
<p><a href="https://en.wikipedia.org/wiki/List_of_Bluetooth_profiles#Audio.2FVideo_Remote_Control_Profile_.28AVRCP.29">AVRCP</a> es un perfil para mandos a distancia de video y de audio,
pero ignoro exactamente cuál es el propósito de este dispositivo de
<em>input</em> en ese contexto.</p>
<h2>En busca del firmware perdido</h2>
<p>Me había costado, pero tras hacer todo lo anterior por fin había
conseguido que funcionara el <em>headset</em> en Debian Jessie. Y colorín
colorado, este cuento se ha acabado. Excepto que no se ha acabado,
porque como no me puedo quedar quieto, hace un par de semanas <a href="http://www.escomposlinux.org/jcantero/ld/2015/06/17/saltando-a-debian-stretch/">salté a
Stretch</a>, con el desastroso resultado de que el <em>headset</em> me
dejó de funcionar. <code>:-(</code></p>
<p>He dicho "me dejó de funcionar" pero en realidad lo que pasaba era lo
siguiente: cuando se enviaba audio a PulseAudio y el <em>headset</em> estaba
encendido, la aplicación que enviaba el audio (exaile, mplayer, etc) se
quedaba "clavada" (la reproducción del audio —y del video también en el
caso de mplayer— no avanzaba). En el caso de exaile, si intentaba parar
la canción la aplicación se quedaba absolutamente congelada. Si apagaba
el <em>headset</em> (lo que conmutaba el audio al <em>sink</em> de ALSA), las
aplicaciones volvían a la vida y el sonido empezaba a reproducirse
normalmente.</p>
<p>Como las diferencias entre Debian Jessie y Debian Stretch son todavía
pequeñas, y el cambio fundamental es que Stretch había actualizado
PulseAudio de la 5.0 a la 6.0, lo que hice fue probar a hacer un
<em>downgrade</em> de los 7 paquetes de PulseAudio que tenía instalados,
sustituyendo las versiones 6.0-2 por las 5.0-13 de Jessie.<sup id="fnref:8"><a class="footnote-ref" href="#fn:8" rel="footnote">8</a></sup> El resto
de paquetes eran los de Stretch, incluyendo BlueZ (que en este caso da
igual porque todavía es exactamente el mismo que el de Jessie). Con los
paquetes 5.0-13 el <em>headset</em> volvía a funcionar sin problemas, lo que me
permitía acotar el problema a los cambios que había introducido
PulseAudio 6.0.</p>
<p>¿Y qué era lo más significativo que había introducido PulseAudio 6.0? Si
habéis seguido atentamente las explicaciones del principio ya sabréis la
respuesta: el soporte de perfiles HSP y HFP, ¡por algo solté todo el
rollo! Y hay otro momento en esta historia en que también se mencionan
dichos perfiles: cuando hablé sobre si necesitaba o no cargar el
firmware propietario de Broadcom en el driver, y de los bugs que
supuestamente éste arreglaba (relacionados con HSP/HFP). Llegados a
este punto, el sentido común dictaba que era conveniente probar a cargar
el firmware a ver si arreglaba algo.</p>
<p>Sólo restaba encontrar el firmware adecuado, lo que ha sido una pequeña
odisea en sí misma. En la página del vendedor de <em>dongles</em> <a href="http://plugable.com/2014/06/23/plugable-usb-bluetooth-adapter-solving-hfphsp-profile-issues-on-linux">que afirmaba
que se necesitaba el firmware para hacer funcionar los perfiles
HSP/HFP</a> (que no es la marca de mi <em>dongle</em> pero que debe
ser un revendedor análogo porque es clavadito al mío) ofrecía para
descargar el siguiente fichero:</p>
<div class="highlight"><pre>-rw-r--r-- 1 ****** ****** 34700 feb 24 2014 fw-0a5c_21e8.hcd
</pre></div>
<p>Buscando por el mismo nombre de fichero, encontré otra versión que tenía
un tamaño diferente (28758 bytes) lo que me dejaba la duda de cuál era
el más reciente. Tampoco me hacía mucha gracia usar un <em>blob</em> opaco
descargado de un sitio <em>random</em> de Internet, pero en la <a href="https://www.broadcom.com/support/?gid=2">página oficial
de Broadcom</a> no hay disponible un driver para descargar del
que poder extraerlo. Lo más que hay es un ejecutable para detectar qué
dispositivo Bluetooth tienes y aparentemente descargarse el driver
adecuado, pero como era previsible no funciona con wine (no es capaz de
pasar de la fase de detección):</p>
<p><img alt="La aplicación de Broadcom ejecutándose en wine" src="http://www.escomposlinux.org/jcantero/ld/images/broadcom-bluetooth-download.jpg" /></p>
<p>(Tampoco funcionó el truco de sacar los <code>strings</code> del ejecutable a ver
si entre ellos aparecía la URL desde la que se descargaban los drivers).</p>
<p>Una alternativa que encontré era seguir estas <a href="http://blog.crox.net/archives/81-Getting-the-Trust-18187-Bluetooth-4.0-USB-adapter-0a5c21e8-to-work-with-Linux.html">instrucciones</a>
para obtener un <code>.hcd</code> a partir de los drivers de Windows. En éstos
existen una serie de ficheros <code>.hex</code> (que parecen simplemente una
versión hexadecimal del firmware) a partir de los cuales se puede
generar el <code>.hcd</code> correspondiente usando la herramienta
<a href="https://github.com/jessesung/hex2hcd">hex2hcd</a>. BlueZ trae esta herramienta (que por cierto en la
versión 5.28 ha sido reescrita) pero Debian a día de hoy no la empaqueta
(<a href="https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=780015">Bug 780015</a>) por lo que si queremos usarla hay que bajarse
el fichero <code>hex2hcd.c</code> y compilarlo a mano.</p>
<p>El problema de este método alternativo es encontrar cuál es el <code>.hex</code>
adecuado, porque hay decenas de ficheros de este tipo en los drivers de
Windows. Hay que buscar la cadena VendorID y ProdID (en mi caso
0A5C:21E8) en los distintos ficheros <code>*.INF</code> hasta dar con la sección
relevante, donde aparecerá algún nombre de fichero como éste:
<code>BCM20702A1_001.002.014.0187.0188.hex</code>. Ese fichero (de tamaño 43432
bytes) es concretamente el que encontré en el CD de drivers que
acompañaba a mi <em>dongle</em>. Para añadir más confusión, el <code>.hcd</code> generado
a partir del mismo tenía un tamaño distinto al de los otros:</p>
<div class="highlight"><pre>-rw-r--r-- 1 ****** ****** 21756 jun 24 16:43 fw-0a5c_21e8-BCM20702A1_001.002.014.0187.0188.hcd
-rw-r--r-- 1 ****** ****** 34700 feb 24 2014 fw-0a5c_21e8.hcd
-rw-r--r-- 1 ****** ****** 28758 jun 24 16:45 otro-fw-0a5c_21e8.hcd
</pre></div>
<p>De todas formas, el fichero <code>.hex</code> extraido del CD de drivers era de
2011, por lo que tenía pinta de ser una versión más antigua del
firmware.</p>
<p>Al final me encontré en una página de soporte de Lenovo unos drivers
Broadcom para Windows de 2013, y en ellos un fichero llamado
<code>BCM20702A1_001.002.014.0889.0896.hex</code> de 57399 bytes, que convertido a
<code>.hcd</code> me daba un fichero exactamente igual que el firmware de 28758
bytes que ya me había bajado antes. Esta es la versión que estoy usando:</p>
<div class="highlight"><pre>usb 3-1.6: new full-speed USB device number 5 using ehci-pci
usb 3-1.6: New USB device found, idVendor=0a5c, idProduct=21e8
usb 3-1.6: New USB device strings: Mfr=1, Product=2, SerialNumber=3
usb 3-1.6: Product: BCM20702A0
usb 3-1.6: Manufacturer: Broadcom Corp
usb 3-1.6: SerialNumber: ------------
Bluetooth: hci0: BCM: chip id 63
Bluetooth: hci0: BCM20702A1 (001.002.014) build 0000
Bluetooth: hci0: BCM20702A1 (001.002.014) build 0896
</pre></div>
<p>La última línea es la del "patch RAM", y ya véis su semejanza al nombre del
fichero <code>.hex</code> utilizado para generarlo.</p>
<p>Lo que no he podido encontrar es un <code>.hex</code> más moderno de un driver más
reciente que se corresponda con el <code>.hcd</code> de 34700 bytes.</p>
<h2>Perfiles, perfiles everywhere</h2>
<p>Una vez puesto el firmware en el path en el que lo busca el driver del
kernel, enciendo el <em>headset</em> y el sonido se escucha ¡Por fin! Pero es
un sonido de una calidad bajísima y con mucha "fritura"<sup id="fnref:9"><a class="footnote-ref" href="#fn:9" rel="footnote">9</a></sup>.</p>
<p>Después de estar un buen rato cavilando qué estaba mal (le estaba
echando la culpa a la versión del firmware), por fin caigo: esa debe ser
la calidad para perfiles HSP/HFP. Lo único que tengo que hacer es
cambiar el perfil:</p>
<div class="highlight"><pre>$ pactl list cards
Card #3
Name: bluez_card.YY_YY_YY_YY_YY_YY
Driver: module-bluez5-device.c
Owner Module: 28
Properties:
device.description = "Energy BT5+"
device.string = "YY:YY:YY:YY:YY:YY"
device.api = "bluez"
device.class = "sound"
device.bus = "bluetooth"
device.form_factor = "headset"
bluez.path = "/org/bluez/hci0/dev_YY_YY_YY_YY_YY_YY"
bluez.class = "0x240404"
bluez.alias = "Energy BT5+"
device.icon_name = "audio-headset-bluetooth"
device.intended_roles = "phone"
Profiles:
headset_head_unit: Headset Head Unit (HSP/HFP) (sinks: 1, sources: 1, priority: 20, available: yes)
a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 10, available: yes)
off: Apagado (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: headset_head_unit
Ports:
headset-output: Headset (priority: 0, latency offset: 0 usec)
Part of profile(s): headset_head_unit, a2dp_sink
headset-input: Headset (priority: 0, latency offset: 0 usec)
Part of profile(s): headset_head_unit
</pre></div>
<p>La sección que nos interesa es la de "Profiles:". Véis que me está detectando
dos perfiles (tres si contáis el perfil "off"). Pero el perfil correspondiente
al HSP/HFP tiene más prioridad (20) que el de A2DP (10), así que se selecciona
por defecto si no le decimos nada. Para cambiar el perfil usamos el siguiente
comando, indicando tarjeta y perfil a activar:</p>
<div class="highlight"><pre>$ pactl set-card-profile 3 a2dp_sink
</pre></div>
<p>Si no queremos indicar el número de tarjeta (que cambia cada vez que se
enciende y apaga el <em>headset</em>) podemos usar el nombre (que permanece
constante pero es más largo):</p>
<div class="highlight"><pre>$ pactl set-card-profile bluez_card.YY_YY_YY_YY_YY_YY a2dp_sink
</pre></div>
<p>El perfil naturalmente tiene que estar disponible (<code>available: yes</code>) o
nos devolverá un error bastante críptico (algo así como "Error de
Entrada/Salida").</p>
<p>Si todo ha ido bien, ahora el estado de la tarjeta que corresponde al
<em>headset</em> tendrá el nuevo perfil activo (Active Profile):</p>
<div class="highlight"><pre>$ pactl list cards
[ ... ]
Profiles:
headset_head_unit: Headset Head Unit (HSP/HFP) (sinks: 1, sources: 1, priority: 20, available: yes)
a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 10, available: yes)
off: Apagado (sinks: 0, sources: 0, priority: 0, available: yes)
Active Profile: a2dp_sink
</pre></div>
<p>Y ahora el audio volverá a oirse con gran calidad con PulseAudio 6.0.
¡¡Hurra!!</p>
<p>(Sí, me podría haber ahorrado la etapa completa de la búsqueda del
firmware, ya que lo único que necesitaba para que el <em>headset</em> volviera
a funcionar en PulseAudio 6.0 era cambiar el perfil a <code>a2dp_sink</code>. Los
bugs que corrige el firmware parece que se limitan al perfil HSP/HFP en
este caso —o tal vez no, pero no he notado la diferencia—. Lo único que
puedo decir es que es fácil hablar a toro pasado <code>:-P</code>).</p>
<p>PulseAudio recuerda el perfil activo de cada tarjeta, así que no hace
falta estar seleccionandolo en cada arranque del demonio. Si lo que
queremos es volver a pasar al perfil HSP/HFP (por ejemplo para usar el
micrófono) hay que volver a cambiar el perfil activo:</p>
<div class="highlight"><pre>$ pactl set-card-profile 3 headset_head_unit
</pre></div>
<p>Observad que <code>a2dp_sink</code> tiene 1 <em>sink</em> y 0 <em>sources</em>, mientras que
<code>headset_head_unit</code> tiene 1 <em>sink</em> y 1 <em>source</em>. Los <em>sinks</em> (sumideros)
corresponden en terminología PulseAudio a las salidas de audio, mientras
que las <em>sources</em> (fuentes) corresponden a las entradas. El perfil de
alta fidelidad A2DP no tiene entradas, por lo que <strong>no se puede</strong> usar
el micrófono con este perfil. Si queremos usar la entrada de audio no
nos queda más remedio que seleccionar el perfil HSP/HFP.<sup id="fnref:10"><a class="footnote-ref" href="#fn:10" rel="footnote">10</a></sup></p>
<p>Hay otra forma más visual de escoger el perfil usando la pestaña
"Configuración" de <code>pavucontrol</code> (PulseAudio Volume Control). Aquí he
preferido usar <code>pactl</code> para mostraros detalles de bajo nivel (como las
prioridades o la disponibilidad) que son útiles si hay problemas.
<code>pavucontrol</code> puede ser más atractivo, pero sólo nos permite seleccionar
el perfil sin darnos información adicional:</p>
<p><img alt="Perfiles en pavucontrol" src="http://www.escomposlinux.org/jcantero/ld/images/pavucontrol-perfiles.png" /></p>
<p>Con tanta prueba y tanto cambio, en algún momento me ha pasado que un
perfil me aparecía como no disponible:</p>
<div class="highlight"><pre>$ pactl list cards
[ ... ]
Profiles:
a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 10, available: no)
headset_head_unit: Headset Head Unit (HSP/HFP) (sinks: 1, sources: 1, priority: 20, available: yes)
off: Apagado (sinks: 0, sources: 0, priority: 0, available: yes)
</pre></div>
<p>Este tipo de estados no deberían ocurrir (y mucho menos que uno aparezca
como disponible y el otro no), pero al estar jugando con los firmwares y
demás tampoco me extraña que de repente haya una discrepancia entre los
datos de estado almacenados por <code>bluetoothd</code> y los de PulseAudio.
Comprobad con <code>bluetoothctl</code> que la conexión está establecida, y si no
es así tratad de establecerla con un <code>connect YY:YY:YY:YY:YY:YY</code>. Si la
conexión no se establece es cuando hay que empezar a investigar.</p>
<p>Otra posibilidad de recuperación más drástica que se me ocurre es tratar
que ambos demonios olviden el estado que tienen almacenado del
dispositivo, y empezar de nuevo todo el proceso de configuración desde
cero. <code>bluetoothctl</code> tiene el comando <code>remove</code> para borrar un
dispositivo remoto, lo que nos permite reemparejarlo de nuevo, pero no
he encontrado ningún método equivalente en PulseAudio. Lo único que se
me ocurre es hacerlo a las bravas: parar el demonio y borrar los
ficheros donde guarda el estado en <code>.config/pulse/*</code>, pero este método
tiene el serio inconveniente de borrar el estado de <strong>todo</strong> (tarjetas,
volúmenes, etc). Si alguien sabe un método mejor estaría bien conocerlo.</p>
<h2>Últimos retoques</h2>
<p>No se me ha olvidado que dije que iba a explicar el origen de estos
mensajes de error y cómo deshacerse de ellos:</p>
<div class="highlight"><pre>bluetoothd[3731]: Sap driver initialization failed.
bluetoothd[3731]: sap-server: Operation not permitted (1)
</pre></div>
<p>SAP son las siglas de <a href="https://developer.bluetooth.org/TechnologyOverview/Pages/SAP.aspx">SIM Access Profile</a>, otro perfil más de
Bluetooth (y ya van...). Aunque un ordenador raramente va a tener acceso
a una tarjeta SIM de teléfono, BlueZ es también la pila Bluetooth usada
en Android<sup id="fnref:11"><a class="footnote-ref" href="#fn:11" rel="footnote">11</a></sup>. Así que los desarrolladores de BlueZ han incluido este
perfil que permite "exportar" la SIM vía Bluetooth a otro dispositivo
(sea cual sea la utilidad de algo así).</p>
<p>El soporte de SAP en BlueZ es experimental, pero los mantenedores del
paquete en Debian han decidido compilar BlueZ con el <em>flag</em>
<code>--enable-experimental</code>, y por eso SAP está incluido en la versión de
<code>bluetoothd</code> de Jessie y Stretch y por eso aparecen esos mensajes. Lo
que no sería mayor problema si no fuera porque mucha gente los confunde
con el motivo por el que su dispositivo Bluetooth no funciona,
mandándoles tras una pista falsa. </p>
<p>La solución más sencilla es pasar de estos mensajes ya que son
inofensivos. Pero si nos resultan realmente irritantes, hay una manera
de hacerlos desaparecer: decirle <code>bluetoothd</code> que desactive el plugin de
SAP pasándole el parámetro <code>--noplugin=sap</code> en el arranque del demonio.
Esto es más fácil o más difícil dependiendo del sistema de arranque que
utilicéis. Por ejemplo, en systemd hay que modificar la unidad
<code>bluetooth.service</code> para añadir el parámetro a la línea de <code>ExecStart</code>
(solo que en systemd se supone que no hay que modificar los ficheros de
unidades suministrados por los <em>packagers</em> sino añadir un fichero de
unidad nuevo bajo <code>/etc/systemd/system/</code> que toma precedencia; consultad
la documentación más reciente de systemd en Debian para estar seguros).</p>
<p>Me dan ganas de abrir un bug en el BTS para que sean los propios Debian
<em>maintainers</em> los que lo añadan por defecto.</p>
<h2>Conclusiones</h2>
<p>El protocolo Bluetooth, al intentar cubrir tantos dispositivos
diferentes y tantos casos de uso, no es precisamente simple. La
implementación en Linux lo empeora con una escasísima documentación y
con cambios significativos a lo largo del tiempo. Si a esto le añadimos
su interacción con otras piezas <a href="http://www.escomposlinux.org/jcantero/ld/2015/05/27/instalando-pulseaudio-en-debian-jessie/"><em>problemáticas</em></a> como
PulseAudio, y lo aderezamos todo con bugs hardware sólo solucionables
mediante ficheros binarios "mágicos" difíciles de encontrar, entonces
uno entiende por qué hay tantísimos problemas con algo que debería ser
aparentemente más sencillo.</p>
<p>He dedicado mucho tiempo a poner el <em>headset</em> en marcha —y a escribir
este artículo también—. Me podría haber ahorrado algo de trabajo si
hubiera sido más espabilado, pero al final hubiera tenido que hacerlo
igualmente si quería usar el micrófono. Y me queda también el consuelo
de que me ha servido para terminar aprendiendo un montón de cosas de
Bluetooth y PulseAudio por el camino. <code>;-)</code></p>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>Se llama <em>headset</em> a una combinación de auriculares y micrófono,
sean con cable o inalámbricos. <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
<li id="fn:2">
<p>El Wiki de Arch Linux es considerado una de las mejores fuentes
de información para configurar cualquier aspecto de Linux. <a class="footnote-backref" href="#fnref:2" rev="footnote" title="Jump back to footnote 2 in the text">↩</a></p>
</li>
<li id="fn:3">
<p>Excepto que todavía uséis una distro con BlueZ 4 o anterior. <a class="footnote-backref" href="#fnref:3" rev="footnote" title="Jump back to footnote 3 in the text">↩</a></p>
</li>
<li id="fn:4">
<p>Los commits en github tienen la pequeña ventaja de mostrar los
tags en los que fueron incluidos, los del interfaz git de
kernel.org no. <a class="footnote-backref" href="#fnref:4" rev="footnote" title="Jump back to footnote 4 in the text">↩</a></p>
</li>
<li id="fn:5">
<p>La magia la hace <a href="https://en.wikipedia.org/wiki/List_of_Bluetooth_protocols#Service_discovery_protocol_.28SDP.29">Service Discovery Protocol (SDP)</a>, que es
el protocolo de Bluetooth para consultar qué perfiles soporta
el dispositivo remoto. <a class="footnote-backref" href="#fnref:5" rev="footnote" title="Jump back to footnote 5 in the text">↩</a></p>
</li>
<li id="fn:6">
<p>De hecho son otorgadas por el mismo organismo y ambas comparten
el espacio de direciones de 48 bits. <a class="footnote-backref" href="#fnref:6" rev="footnote" title="Jump back to footnote 6 in the text">↩</a></p>
</li>
<li id="fn:7">
<p>¡La de bromas que íbais a gastar en la oficina! <code>}:-P</code> <a class="footnote-backref" href="#fnref:7" rev="footnote" title="Jump back to footnote 7 in the text">↩</a></p>
</li>
<li id="fn:8">
<p>Hay que ser cuidadoso cuando se hacen este tipo de cosas si no
se quiere terminar con el sistema medio roto. <a class="footnote-backref" href="#fnref:8" rev="footnote" title="Jump back to footnote 8 in the text">↩</a></p>
</li>
<li id="fn:9">
<p>Argot de radioaficionados. <a class="footnote-backref" href="#fnref:9" rev="footnote" title="Jump back to footnote 9 in the text">↩</a></p>
</li>
<li id="fn:10">
<p>He probado el micro usando la grabación desde audacity y me
funciona. <a class="footnote-backref" href="#fnref:10" rev="footnote" title="Jump back to footnote 10 in the text">↩</a></p>
</li>
<li id="fn:11">
<p>Aunque le fastidie a Google (ya que lleva licencia GPL). <a class="footnote-backref" href="#fnref:11" rev="footnote" title="Jump back to footnote 11 in the text">↩</a></p>
</li>
</ol>
</div>Coloreado de sintaxis en vim2015-07-01T13:05:00+02:00Javier Canterotag:www.escomposlinux.org,2015-07-01:jcantero/ld/2015/07/01/coloreado-de-sintaxis-en-vim/<p><a href="http://vimcolors.com/">~/.vim/colors</a> es una web que recoge diferentes estilos de
coloreado de sintaxis en vim. El único problema es que, como algunos
comentan, un esquema de color que puede ser agradable para un lenguaje
de programación puede ser todo lo contrario para otro, y esto no nos
permite compararlo.</p>
<p>Hay otra página web, <a href="https://code.google.com/p/vimcolorschemetest/">vimcolorschemetest</a><sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>, que
sí que nos permite hacer una comparación por lenguaje, pero realmente
hay muy pocos (y eso incluyendo como "lenguajes" HTML y LaTeX). Al menos
<a href="http://vimcolorschemetest.googlecode.com/svn/html/index-c.html">sí compara C</a>.</p>
<p>No es fácil decidirse, ¿eh? <code>}:-)</code></p>
<p>Los esquemas que os gusten los guardáis en <code>.vim/colors/</code> y los activáis
con <code>:colorscheme nombre</code> (o <code>:colo nombre</code>). Para activar uno siempre
por defecto poned <code>colorscheme nombre</code> antes del <code>syntax on</code> en el
<code>.vimrc</code>.</p>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>por favor que alguien les avise que migren de Google Code <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>Desaparece evince-gtk de Debian Stretch2015-06-30T16:34:00+02:00Javier Canterotag:www.escomposlinux.org,2015-06-30:jcantero/ld/2015/06/30/desaparece-evince-gtk-de-debian-stretch/<p>Para mi sorpresa, la actualización de Debian Stretch de hoy pretendía
instalarme evince además de actualizarme evince-gtk. Investigando un poco, en
el ChangeLog del paquete source de evince me encuentro esto:</p>
<div class="highlight"><pre> * Build only the full-flavored variant of Evince (Closes: #755071).
+ Disable building of the evince-gtk flavor.
+ Turn evince-gtk into a transitional package that depends on evince.
+ Add Breaks and Replaces to the evince package accordingly.
+ Move gvfs from Recommends to Suggests.
[...]
</pre></div>
<p>Así que lo que ha pasado es que directamente se han cargado evince-gtk
(convirtiéndolo en un paquete transicional <em>dummy</em>) y en su lugar instalan la
versión evince de GNOME <a href="https://packages.debian.org/stretch/evince-gtk">por dependencias</a>, negándonos el
motivo a los que usábamos evince-gtk precisamente porque <strong>no</strong>
queríamos usar dicha versión.</p>
<p>La decoración de la ventana de evince ya hace tiempo que no pegaba ni con cola
con el resto de la del sistema, pero es ahora cuando me doy cuenta que no era
por rollos entre GTK2 y GTK3, sino porque pretendían darme gato por liebre. Si
escogí evince-gtk <a href="http://www.escomposlinux.org/jcantero/ld/2014/01/07/xpdf-poppler-fontconfig/">como sustituto de xpdf</a> era por tener un lector de
PDF ligero, moderno y sobre todo independiente de escritorio, para que se
integrara como una aplicación más dentro de Xfce. Pero evince a secas no es una
aplicación agnóstica, es una aplicación GNOME con todas las consecuencias, por
lo que no me interesa. Y ahora me tocará buscarme otra alternativa.</p>
<p>Ya está bien, gente de GNOME. En vez de solucionar problemas lo único que
hacéis es dar más trabajo. Luego os extrañará la creciente animadversión hacia
vosotros y vuestro proyecto.</p>
<p>:wq</p>Aún más privacidad para Firefox (e Iceweasel)2015-06-27T13:34:00+02:00Javier Canterotag:www.escomposlinux.org,2015-06-27:jcantero/ld/2015/06/27/aun-mas-privacidad-para-firefox-e-iceweasel/<p>Iceweasel 38 de Debian Stretch está basado en Firefox 38, que es la
versión que incorpora funcionalidad muy polémica como el <a href="http://www.escomposlinux.org/jcantero/ld/2015/05/13/firefox-como-firefox-alternativo-sin-drm/">módulo EME de
DRM</a>, el <a href="https://www.firefox.com/hello/">servicio centralizado Hello de WebRTC</a> o la
<a href="https://blog.mozilla.org/futurereleases/2015/05/13/get-a-firefox-account-and-test-new-features-in-firefox-beta/">integración con el servicio propietario Pocket</a>.</p>
<p>A alguna gente le preocupa enormemente el impacto que estas novedades
puedan tener en la privacidad de los usuarios de Firefox/Iceweasel, y
están compartiendo información sobre distintas opciones escondidas en la
interfaz de <code>about:config</code> para eliminar/desactivar/mitigar estas
amenazas a la privacidad (como por ejemplo <a href="https://github.com/amq/firefox-debloat">firefox
debloat</a>). Yo también me quiero apuntar a la moda ofreciendo
mis propias sugerencias de cosas a tocar en el <code>about:config</code>, que
podéis considerar un <em>addendum</em> a <a href="http://www.escomposlinux.org/jcantero/ld/2015/05/25/incrementando-la-privacidad-en-firefox/">"Incrementando la privacidad en
Firefox"</a>.</p>
<p>Por ejemplo, para deshabilitar Pocket (a partir de Firefox 38.0.5 por lo
que aún no existe en la Iceweasel 38.0.1 de Stretch), aparte de poner a
false la opción <code>browser.pocket.enabled</code> vamos a fastidiar otras
opciones de la configuración para que no pueda funcionar bien,
sustituyendo las URLs por enlaces a localhost (o 127.0.0.1, como
prefiráis) y poniendo una clave oAuth inválida:</p>
<div class="highlight"><pre>browser.pocket.api localhost
browser.pocket.site localhost
browser.pocket.enabled false
browser.toolbarbuttons.introduced.pocket-button false
browser.pocket.oAuthConsumerKey pure-garbage-ajahfuabqfaklsdfbah
</pre></div>
<p>De esta forma, aunque alguna actualización posterior reactive
subrepticiamente Pocket, va a tener difícil filtrar nada si no se les
ocurre además restablecer las otras opciones.</p>
<p>Para evitar el módulo EME de DRM lo mejor es usar una <a href="http://www.escomposlinux.org/jcantero/ld/2015/05/13/firefox-como-firefox-alternativo-sin-drm/">versión sin
EME</a>. Las versiones de Linux aun no tienen incorporado este
módulo, y yo espero que los mantenedores de Iceweasel se nieguen a
incorporarlo. De todas formas si queréis poner:</p>
<div class="highlight"><pre>media.eme.enabled false
</pre></div>
<p>tampoco está de más.</p>
<p>Con respecto a Hello, parece que se conecta a servidores de terceras
partes (concretamente suministrados por Telefónica) sin avisar de ello
cuando establece una comunicación WebRTC. Supuestamente se hace para
permitir la conexión aun en los casos en que ambos navegadores están
tras un NAT. Si queréis evitarlo la opción es <code>loop.enable</code> a false,
pero además podemos hacer como antes y hacer un estropicio con el resto
de opciones relacionadas:</p>
<div class="highlight"><pre>loop.enabled false
loop.gettingStarted.url localhost
loop.learnMoreUrl localhost
loop.legal.ToS_url localhost
loop.legal.privacy_url localhost
loop.oauth.google.scope localhost
loop.server localhost
loop.showPartnerLogo false
loop.support_url localhost
</pre></div>
<p>Para que no se muestren las pestañas con "sitios sugeridos":</p>
<div class="highlight"><pre>browser.newtab.url about:blank
</pre></div>
<p>El servicio de salud y la telemetría parece que vienen desactivados en
Iceweasel, en el caso de Firefox deberíais revisarlos (opciones
<code>datareporting.healthreport.*</code> y <code>toolkit.telemetry.*</code>).</p>
<p>Otros que ya deberíais tener puestos de anteriores artículos:</p>
<div class="highlight"><pre>browser.safebrowsing.enabled false
browser.safebrowsing.downloads.enabled false
browser.safebrowsing.malware.enabled false
geo.enabled false
media.peerconnection.enabled false
privacy.trackingprotection.enabled true
</pre></div>
<p>Los 3 primeros son servicios de Google para detectar páginas y descargas
con malware, y alguna gente opina que desactivarlos hace más mal que
bien. A mi me parece que es el equivalente a pensar que a uno no le van
a entrar virus porque tiene un antivirus (los "malos" siempre suelen ir
por delante de los usuarios, así que el navegador no considere una
página maliciosa no significa que no lo sea). No obstante, reconozco que
puede ser útil dejárselo puesto a vuestra mamá.</p>
<p>Seguro que hay muchas más que me dejo, y que se puede enredar aún más
con las opciones para obstaculizar cualquier intento de pasar datos
hacia Internet, sembrando el caos en URLs etcétera. Pero eso lo dejo
como ejercicio para el lector interesado.</p>
<p>:wq</p>Poniéndole la correa a systemd en Debian Stretch2015-06-26T19:09:00+02:00Javier Canterotag:www.escomposlinux.org,2015-06-26:jcantero/ld/2015/06/26/poniendole-la-correa-a-systemd-en-debian-stretch/<p>Estaba pendiente del momento en el que la versión actual de systemd en
sid —la 220— intentara entrar en testing para pararlo, y ese día ha
sido hoy. Apenas han asomado la patita, les he plantado un <em>hold</em> a los
8 paquetes de systemd que pretendían actualizarse:</p>
<div class="highlight"><pre><span class="c"># aptitude hold libpam-systemd libsystemd0 libsystemd0:i386 libudev1 libudev1:i386 systemd systemd-sysv udev</span>
</pre></div>
<p>De paso he evitado que la actualización tratara de instalarme un par de
dependencias nuevas de systemd: libapparmor y libseccomp. Teniendo en
cuenta que AppArmor y demás frameworks de seguridad no están compilados
en mi kernel, estas bibliotecas no eran más que potenciales fuentes de
futuros problemas.</p>
<p>Mi plan es aguantar en systemd 215 tanto como pueda. La ventaja es que
la 215 es la versión que lleva Debian Jessie, con lo que si hubiera
algún problema de seguridad en esa versión, el equipo de seguridad de
Debian sacaría nuevos paquetes que yo también podría usar para
actualizar mi testing, aunque tuviera que ser a mano mediante <code>dpkg
-i</code><sup id="fnref:1"><a class="footnote-ref" href="#fn:1" rel="footnote">1</a></sup>.</p>
<p>El motivo de esta decisión tan rara es librarme tanto tiempo como pueda
de <a href="https://news.ycombinator.com/item?id=8595335">porquerías como systemd-resolved</a>. Más adelante ya veré
qué es lo que hago.</p>
<p>:wq</p>
<div class="footnote">
<hr />
<ol>
<li id="fn:1">
<p>Hay otros métodos, pero no creo que haya tantas actualizaciones
como para que merezca la pena mezclar orígenes de Jessie y Strech <a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text">↩</a></p>
</li>
</ol>
</div>Linux 4.12015-06-25T12:29:00+02:00Javier Canterotag:www.escomposlinux.org,2015-06-25:jcantero/ld/2015/06/25/linux-41/<p>Y <em>habemus</em> una nueva versión del kernel, la 4.1, listo para descargar
como siempre desde <a href="https://www.kernel.org/">kernel.org</a>. Yo ya la tengo compilada y
funcionando —en principio— sin problemas.</p>
<p>Como pasa con los kernels recientes tampoco hay muchas novedades
llamativas en Linux 4.1. De cara al usuario destaca el <a href="http://lwn.net/Articles/639427/">nuevo soporte de
cifrado en ext4</a>, con el que podréis cifrar determinados
ficheros y directorios —en vez de la partición o todo el disco como
hacen otras soluciones—. En principio esta opción está sólo disponible
si usáis este sistema de ficheros, pero ya se está hablando de
generalizarlo para que se pueda usar con otros <em>filesystems</em>.</p>
<p>En cuanto al soporte de nuevo hardware, lo más significativo es la
primera implementación del soporte de <a href="https://en.wikipedia.org/wiki/Persistent_memory">memoria persistente</a>, que
parece estar destinada a convertirse en la "Next Big Thing" de la
arquitectura de computadores. De todas formas, en esta primera
aproximación los desarrolladores del kernel han sido bastante
conservadores e implementan la memoria persistente como un dispositivo
de bloque más, para usarla como si fuera un disco. En el futuro tendrán
que aparecer aproximaciones más atrevidas si se quiere sacar realmente
jugo a esta tecnología, aunque suponga un cambio radical en la forma
actual de entender el funcionamiento de un ordenador (y una
reimplementación de muchas partes fundamentales del kernel).</p>
<p>Para profundizar como siempre recomiendo los artículos de LWN.Net
(<a href="http://lwn.net/Articles/640297/">1</a>, <a href="http://lwn.net/Articles/641016/">2</a>, <a href="http://lwn.net/Articles/642039/">3</a>) y la (futura) <a href="http://kernelnewbies.org/Linux_4.1">sección de
ChangeLog de KernelNewbies</a> como las fuentes de
información más exhaustivas de los cambios que trae cada nueva versión
del kernel.</p>
<p>Y en la sección de curiosidades, un <a href="http://i.imgur.com/kMGIVN0.jpg">Linux 4.1.15-1.1381_SKYN12nnmp es
la versión del kernel que parece que usa SkyNet para sus Terminators
T-800</a>. Si a esto le sumáis que Linux 4.1 ha sido
declarada versión <em>long term support</em>... <code>}:-)</code></p>
<p>:wq</p>