25 de noviembre de 2019

Las novedades de Linux 5.4

Ya se ha publicado Linux 5.4. Las novedades de esta versión incluye el "kernel lockdown mode", con el que se pretende proteger los límites entre UID 0 y el kernel; virtio-fs, un driver virtio que permite a un huésped virtualizado montar sistemas de archivos del anfitrión; fs-verity, que permite detectar modificaciones no autorizadas en los archivos; dm-clone, que permite la clonación en vivo de targets de device-mapper; dos nuevas banderas en madvise() para mejor gestión de memoria de las aplicaciones en Android; soporte para nuevas GPUs Intel y AMD; soporte para el sistema de archivo exfat y eliminación del estatus experimental de erofs; soporte para haltpoll, un nuevo driver cpuidle que mejora el rendimiento en huéspedes virtualizados que quieren hacer polling en el loop idle; y blk-iocost, un controlador de cgroup E/S que intenta calcular mejor el coste de la E/S. Además, hay muchas otras mejoras y pequeños parches. La lista completa de cambios, en inglés, se encuentra aquí.


· Kernel lockdown mode


Esta versión incluye un modo opcional "kernel lockdown", que pretende fortalecer los límites entre UID 0 (root) y el kernel. Cuando se activa, se restringe la funcionalidad de varios aspectos del kernel. Las aplicaciones que dependen de acceso de bajo nivel o bien al hardware o al kernel podrían dejar de funcionar; por lo tanto debe evaluarse con antelación su activación. El propósito original de esta característica era honrar las protecciones anti-manipulación que se esperan de los entornos con arranque seguro UEFI, pero no está limitado a esa función.

Se ha implementado Kernel Lockdown como un módulo de seguridad de Linux, que puede configurase en modo de integridad o lockdown. Si se configura con modo integridad, se desactivarán las características del kernel que permiten modificar el kernel. Si se configura con modo de confidencialidad, también se desactivarán las características que permiten a los programas extraer información del kernel (estas restricciones no sólo se aplicarán a los programas de usuarios normales, sino también, recordemos, al usuario root). La configuración puede hacerse a través de securityfs, con un parámetro de arranque o en tiempo de compilación.

· virtio-fs, un puente para compartir sistemas de archivos con huéspedes virtualizados

Esta versión incluye virtio-fs, un driver virtio basado en FUSE que se utiliza para compartir sistemas de archivos entre huéspedes <-> anfitriones. Permite a un huésped montar un directorio que haya sido exportado desde el anfitrión. Aunque hay tecnologías similares que permiten este tipo de funcionalidad (NFS, virtio-9P), la proximidad entre VMs de virtio-fs permite aventajarles y proporcionar un rendimiento y unas semánticas de las APIs más similares a un sistema de archivos local que uno remoto.

<->· fs-verity, para la detección de modificaciones en archivos
<->fs-verity es una capa que los sistemas de archivos pueden utilizar para soportar transparentemente la protección de integridad y autenticidad de archivos de sólo lectura. Es similar a dm-verity, pero funciona a nivel de archivos, en lugar de bloques. Es utilizado por Ext4 y F2FS.
<->
<->Los programas pueden utilizar una ioctl que provoca que el sistema de archivos construya un árbol Merkle para el archivo que persista en alguna ubicación asociada con el archivo. Opcionalmente, es posible firmar archivos con una clave cargada en el keyring. Tras esta operación, el archivo se convierte en un archivo de sólo lectura, y todas las lecturas del archivo serán verificadas contra el árbol Merkle del archivo, con lo que se podrán detectar cualquier modificación, intencionada o no. Los programas pueden también obtener con rapidez el hash raíz del archivo con otra ioctl, lo cual puede ser utilizado para una serie de funcionalidades de seguridad. Para más detalles lean la<-> documentación.

<->· dm-clone
<->dm-clone es un target de device-mapper que hace una copia de una fuente de sólo lectura en un dispositivo de destino: Presenta un dispositivo de bloques virtual que muestra inmediatamente todos los datos, y redirige las lecturas y escrituras cuando sea necesario. El uso principal de dm-clone es clonar un dispositivo de bloques remoto, de alta latencia, en un dispositivo rápido y local. El dispositivo montado es inmediatamente visible y la copia de datos ocurre en segundo plano, en paralelo con la E/S de usuario.

<->· Soporte de nuevo hardware gráfico Intel/AMD
<->
<->
<->
Esta nueva versión añade soporte en el driver amdgpu para cuatro nuevos productos:: Navi 12/14, Arcturus y Renoir.<-><-> 

<->También incluye las primeras partes del soporte del futuro Intel Tiger Lake.
<->
<->· Dos nuevas banderas en madvise(): MADV_COLD y MADV_PAGEOUT
<-> Para mejorar el uso de memoria en algunos sistemas (notablemente, Android), se han incorporado dos nuevas banderas a madvise(): MADV_COLD y MADV_PAGEOUT. Estas dos nuevas banderas complementan a MADV_DONTNEED y MADV_FREE añadiendo formas no destructivas de recuperar memoria libre.
<->
<->MADV_COLD advierte al kernel de que las páginas pueden ser reclamadas cuando haya presión de memoria pero los datos deberían preservarse para el futuro, esto puede reducir el desalojo de la memoria utilizada y por lo tanto mejorar el rendimiento. Como contraste con MADV_FREE, los contenidos de la región son preservados al margen de que después se escriba a las páginas.
<->
MADV_PAGEOUT puede utilizarse por un proceso para marcar un rango de memoria como que no espera ser utilizado por un largo tiempo, de modo que el kernel reclame cualquier página de la LRU instantáneamente. El indicio puede ayudar al kernel a decidir qué páginas desalojar proactivamente. El acceso al rango tras una operación exitosa puede provocar fallos de página mayores, pero nunca perder los contenidos actualizados como ocurre con MADV_DONTNEED.
<->
<->· Erofs y exfat
<->Esta saca a erofs fuera del espacio de staging. Incluído por primera vez en Linux 4.19, erofs es un sistema de archivos de sólo lectura, con un diseño moderno para escenarios en los que se necesitan medios de sólo lectura de alto rendimiento, como firmwares de teléfonos o livecds. 

Esta versión también añade el sistema de archivos exfat al área staging.

· Polling más eficiente en huéspedes virtualizados con haltpoll
<->Esta versión incluye un driver cpuidle y un governor asociado llamados haltpoll. Estos dos mechanismos permiten a las CPUs virtuales continuar haciendo poll durante una determinada cantidad de tiempo antes de detenerse, lo cual proporciona una serie de ventajas considerables como evitar el coste de una VM-exit, que acaba traduciéndose en un mejor rendimiento. Para más detalles, lean la documentación.
<->
<->· blk-iocost, un controlador de E/S más preciso 
<->Una de las dificultades de controlar los recursos de E/S es la dificultad de observar su coste. El ancho de banda y las operaciones por segundo pueden variar enormemente dependiendo del tipo de dispositivo y de los patrones de E/S utilizados. Esto es un reto para los controladores cgroup de E/S, que deben poder calcular el coste de la E/S para hacer su trabajo: a pesar de que io.latency proporciona la capacidad de priorizar y proteger unas E/S sobre otras de otros cgroups, en la práctica su protección es binaria - el cgroup con el objetivo con mejor latencia es protegido a pesar del resto.

<->
Esta versoión incluye blk-iocost, un controlador con un modelo de coste de E/S que intenta ser más efectivo. Tiene un modelo donde cada E/S está clasificada como secuencial o aleatoria y se le da un coste base acorde. Cada E/S obtiene un coste bastante fiable, y distribuye la capacidad de E/S a cada cgroup de acuerdo con su peso jerárquico. Para más detalle, lean la documetación de io.cost.qos y io.cost.model<->.

<->· Espacio de nombres en los símbolos del kernel
<->Para soportar los módulos, el kernel necesita exportar los símbolos de las funciones utilizadas por los módulos. Con más de 30k símbolos en el kernel actual, gestionar todos los símbolos no es siempre fácil. En esta versión, el kernel permite a los mantenedores de subsistemas particionar y categorizar sus símbolos exportados en nombres de espacios diferentes, lo cual facilita el control de los símbolos. Los autores de módulos deben importar los espacios de nombres que quieran utilizar.

<->
Y eso es todo. Como siempre, pueden encontrar la lista completa de cambios, en inglés, en esta página.





<->

6 de mayo de 2019

Las novedades de Linux 5.1

Ya se ha publicado la versión 5.1 de Linux. Entre los cambios que trae consigo está versión se encuentra: io_uring, una nueva interfaz de alto rendimiento para E/S asíncrona; también se incluyen mejoras a fanotify que proporcionan una manera escalable de vigilar los cambios en sistemas de archivos grandes; se añade un método para permitir la entrega segura de señales en presencia de reutilización de PIDs; la memoria persistente puede utilizarse como RAM; los niveles de compresión Zstd en Btrfs son configurables; también se añade un nuevo gobernador cpuidle que toma mejores decisiones de gestión energética que el gobernador menu; todas las arquitecturas de 32 bits han añadido llamadas al sistema con time_t de 64 bits para afrontar el problema y2038; es posible arrancar desde un dispositivo de device-mapper sin usar initramfs; y el parcheo en vivo ha añadido soporte para parches acumulativos. Además, hay muchas otras mejoras y pequeños parches. La lista completa de cambios, en inglés, se encuentra aquí.


1. E/S asíncrona de alto rendimiento con io_uring

Linux soporta E/S asíncrona desde hace mucho tiempo. Sin embargo, la interfaz tiene un amplio número de problemas. No soporta, por ejemplo, E/S con búfers, sólo E/S sin buffers (O_DIRECT), que sólo utiliza un subconjunto de un subconjunto de aplicaciones. Incluso en esos casos, la E/S no era siempre asíncrona ni rápida. Todos los intentos de mejorar la interfaz existente han fracasado. 

Esta versión incluye una nueva interfaz, io_uring, que trae a Linux E/S asíncrona rápida y escalable, tanto con búfers como sin ellos, y soporta también E/S asíncrona con polling. Para más detalles, lea este  documento (PDF) que explica las razones por las que se ha creado io_uring, su funcionamiento interno, y la interfaz de cara al usuario. Para detalles sobre el rendimiento, vea este email.

Adicionalmente, se ha creado una librería, liburing, para las aplicaciones que no necesitan o no quieran preocuparse de juguetear con los detalles de bajo nivel de la interfaz. Tiene ayudantes que permiten a las aplicaciones configurar una instancia io_uring y enviar/completar E/S  in conocer los detalles más escabrosos de los anillos; continuará añadiendo ayudantes y más características con el tiempo.

2. Mejoras en fanotify para una mejor monitorización del sistema de archivos

A diferencia de otros sistemas operativos, Linux no proporciona un sistema eficiente para vigilar los cambios que ocurren en un sistema de archivos grande. La única manera de monitorizar eventos de modificación a un directorio es inotify, que escala mal con grandes árboles de directorios. La interfaz fanotify, introducida en Linux 2.6.36, tenía la pretensión de sustituir inotify y solucionar sus deficiencias, e inicialmente dió algunos pasos en esa dirección, pero la funcionalidad requerida para sustituir a inotify por completo.

Esta versión (junto con los cambios añadidos en Linux 4.20) expanden inotify para proporcionar la funcionalidad "super block root watch", que es una manera escalable de observar los cambios en grandes sistemas de archivos. Para más detalles, lea el wiki del proyecto.

3. Entrega segura de señales en presencia de reutilización de PID

La llamada al sistema kill(2) opera con PIDs. Tras la salida y muerte de un proceso, su numero de PID puede ser reutilizado por otro proceso. Si un proceso envía una señal a un PID reutilizado, estará enviando la señal al PID equivocado. Este es un problema conocido con el diseño de Unix, y ha provocado numerosos problemas de seguridad.

Tras considerar varias opciones, Linux ha añadido la llamada al sistema pidfd_send_signal(2), que utiliza descriptores de archivo de /proc/ para referencias a struct pid. Incluso tras el reciclado de un número PID, el descriptor no cambiará y hará referencia al viejo PID y no al nuevo, lo cual permite enviar señales al PID que en verdad se desea.

4. Utilización de memoria persistente como RAM

Linux soporta dispositivos de memoria persistente, pero normalmente son utilizados como dispositivos de almacenamiento. Algunas personas desean utilizar la memoria persistente como memoria volátil, están dispuestos a lidiar con las diferencias de rendimiento con la RAM, y quieren utilizar las APIs tradicionales de gestión de memoria en lugar de un asignador de memoria en espacio de usuario ubicado sobre el mmap() de un archivo DAX. Esta versión de Linux les permite hacer eso.

5. TEO, un gobernador alternativo a 'menu'

El  subsistema cpuidle es la parte del kernel encargada de decidir qué estado de sueño profundo utilizar cuando la CPU no tiene nada que hacer (los estados de sueño más profundo ahorran más energía, pero cuesta más salir de ellos). Hay dos gobernadores cpuidle, "menu" y "ladder", cada uno con diferentes heurísticas. Sin embargo, se cree que el gobernador "menu" tiene una serie de deficiencias que han llevado a añadir una alternativa: TEO, Timer Events Oriented Governor, que parece ofrecer mejoras de rendimiento sin aumento del consumo de energía. Puede observarse el gobernador que está siendo utilizado en /sys/devices/system/cpu/cpuidle/current_governor_ro, y cambiar el gobernador por defecto en el arranque con el parámetro cpuidle.governor=teo.

6. Más preparación para el año 2038

Como parte del trabajo para prepararse para el problema del año 2038, esta versión incluye llamadas de sistema con time_t de 64 bits para todas las arquitecturas de 64 bits. Esto permite finalmente tener llamadas al sistema con 64-bit time_t en todas las arquitecturas.

7. Compresión Zstd configurable para Btrfs

Btrfs tiene soporte de compresión Zstd desde Linux 4.14, pero no permitía configurar el nivel de compresión utilizado. Esta versión añade soporte para configurar el nivel de compresión en Btrfs, como se hace con zlib, utilizando la opción de montaje -o compress=zstd:nivel. Para ver los niveles disponibles y su impacto en el rendimiento y en el ratio de compresión, vea este commit.

8. Arranque desde un dispositivo de device mapper sin initramfs

Para arrancar a un sistema de archivos ubicado en un dispositivo device mapper, se necesita un initramfs. Algunas personas, sin embargo, querrían o no pueden usar un initramfs. Esta versión permite utilizar targets DM en el proceso de arranque sin la necesidad de initramfs, con la ayuda de un complicado parámetro de arranque del kernel. Para más detalles vean la  documentación.

9. parcheado en vivo: soporte para parches acumulativos

Puede haber dependencias entre los parches en vivo. Si diferentes parches necesitan hacer diferentes cambios a la misma función, es necesario definir el orden en el que los parches serán instalados. Y implementaciones de funciones en los parches en vivo más nuevos deberán realizarse encima de los viejos, algo que pronto se convierte en una pesadilla para mantener, especialmente si alguien quiere eliminar uno de los parches que está en medio de la pila. Una solución elegante que se incluye en esta versión es algo llamado "reemplazo atómico". Permite la creación de "parches acumulativos" que incluyen todos los cambios de los parches viejos y los reemplazan por completo en una sóla transición. Como resultado, los autores de parches en vivo pueden mantener las fuentes para un sólo parche acumulativo. Para más detalles, vea la documentación

Y eso es todo. Como siempre, pueden encontrar la lista completa de cambios, en inglés, en esta página.