Sistemas de archivos virtuales de Linux: ¿por qué son necesarios y cómo funcionan? Parte 2

Hola a todos, estamos compartiendo con ustedes la segunda parte de la publicación "Sistemas de archivos virtuales en Linux: ¿por qué son necesarios y cómo funcionan?" La primera parte se puede leer aquí . Recuerde que esta serie de publicaciones está dedicada al lanzamiento de un nuevo hilo en el curso de Administrador de Linux , que comenzará muy pronto.

Cómo ver VFS con herramientas eBPF y bcc

La forma más fácil de comprender cómo funciona el núcleo en los archivos sysfs es mirarlo en la práctica, y la forma más fácil de observar ARM64 es usar eBPF. eBPF (abreviatura de Berkeley Packet Filter) consiste en una máquina virtual que se ejecuta en el núcleo que los usuarios privilegiados pueden query desde la línea de comandos. Las fuentes del núcleo le dicen al lector lo que el núcleo puede hacer; Ejecutar herramientas eBPF en un sistema ocupado muestra lo que el núcleo hace realmente.



Afortunadamente, comenzar a usar eBPF es bastante fácil con las herramientas bcc , que están disponibles como paquetes de la distribución general de Linux y están documentadas en detalle por Bernard Gregg . bcc herramientas bcc son scripts de Python con pequeñas inserciones de código C, lo que significa que cualquiera que esté familiarizado con ambos lenguajes puede modificarlos fácilmente. Hay 80 scripts de Python en bcc/tools , lo que significa que lo más probable es que el desarrollador o administrador del sistema pueda elegir algo adecuado para resolver el problema.

Para tener una idea superficial de lo que hace VFS en un sistema en ejecución, pruebe vfscount o vfsstat . Esto mostrará, por ejemplo, que docenas de llamadas a vfs_open() y "sus amigos" ocurren literalmente cada segundo.



vfsstat.py es un script de Python con inserciones de código C que simplemente cuenta las llamadas a funciones VFS.


Damos un ejemplo más trivial y vemos qué sucede cuando insertamos una unidad flash USB en una computadora y el sistema la detecta.



Con eBPF, puede ver lo que sucede en /sys cuando se inserta una unidad flash USB. Aquí se muestra un ejemplo simple y complejo.


En el ejemplo anterior, la herramienta bcc trace.py muestra un mensaje cuando se sysfs_create_files() comando sysfs_create_files() . Vemos que sysfs_create_files() se lanzó utilizando la secuencia de kworker en respuesta a la unidad flash que se está insertando, pero ¿qué archivo se creó? El segundo ejemplo muestra todo el poder de eBPF. Aquí trace.py muestra la trace.py del núcleo (opción -K) y el nombre del archivo creado por sysfs_create_files() . La inserción de una sola declaración es un código C que incluye una cadena de formato fácilmente reconocible proporcionada por un script Python que ejecuta el compilador LLVM justo a tiempo . Compila y ejecuta esta línea en una máquina virtual dentro del núcleo. La firma completa de la función sysfs_create_files () debe reproducirse en el segundo comando para que la cadena de formato pueda hacer referencia a uno de los parámetros. Los errores en este fragmento de código C dan como resultado errores reconocibles del compilador de C. Por ejemplo, si omite la opción -l, verá "Error al compilar el texto BPF". Los desarrolladores que estén familiarizados con C y Python encontrarán que las herramientas bcc fáciles de expandir y modificar.

Cuando se inserta una unidad USB, un kworker núcleo mostrará que PID 7711 es la secuencia de kworker que creó el archivo de «events» en sysfs . En consecuencia, una llamada con sysfs_remove_files() mostrará que al eliminar la unidad se ha eliminado el archivo de events , que está en línea con el concepto general de conteo de referencias. Al mismo tiempo, ver sysfs_create_link () con eBPF mientras inserta una unidad USB mostrará que se crean al menos 48 enlaces simbólicos.

Entonces, ¿cuál es el significado del archivo de eventos? El uso de cscope para buscar __device_add_disk () muestra que llama a disk_add_events () , y se puede escribir "media_change" o "eject_request" en el archivo de evento. Aquí, la capa de bloque del núcleo informa al espacio de usuario de la apariencia y extracción del "disco". Tenga en cuenta cuán informativo es este método de investigación con el ejemplo de insertar una unidad USB en comparación con tratar de descubrir cómo funciona todo, exclusivamente desde la fuente.

Los sistemas de archivos raíz de solo lectura permiten dispositivos integrados

Por supuesto, nadie apaga el servidor o su computadora, desconectando el enchufe. Pero por que? Y todo porque los sistemas de archivos montados en dispositivos de almacenamiento físico pueden tener registros pendientes, y las estructuras de datos que registran su estado pueden no estar sincronizadas con los registros en el almacenamiento. Cuando esto sucede, los propietarios del sistema tienen que esperar al próximo arranque para ejecutar la utilidad de fsck filesystem-recovery y, en el peor de los casos, perder datos.

Sin embargo, todos sabemos que muchos dispositivos IoT, así como enrutadores, termostatos y automóviles ahora están ejecutando Linux. Muchos de estos dispositivos prácticamente no tienen interfaz de usuario, y no hay forma de apagarlos "limpiamente". Imagínese arrancar un automóvil con una batería descargada, cuando la potencia del dispositivo de control en Linux sube y baja constantemente. ¿Cómo es que el sistema arranca sin un fsck largo cuando el motor finalmente comienza a funcionar? Y la respuesta es simple. Los dispositivos integrados se basan en un sistema de archivos raíz de solo lectura (abreviado como ro-rootfs (sistema de archivos raíz de solo lectura)).

ro-rootfs ofrece muchos beneficios que son menos obvios que los genuinos. Una ventaja es que el malware no puede escribir en /usr o /lib si ningún proceso de Linux puede escribir allí. Otra es que un sistema de archivos en gran parte inmutable es crítico para el soporte de campo para dispositivos remotos, ya que el personal de soporte utiliza sistemas locales que son nominalmente idénticos a los sistemas locales. Quizás la ventaja más importante (pero también la más insidiosa) es que ro-rootfs obliga a los desarrolladores a decidir qué objetos del sistema no cambiarán, incluso en la etapa de diseño del sistema. Trabajar con ro-rootfs puede ser incómodo y doloroso, como suele ser el caso con las variables constantes en los lenguajes de programación, pero sus beneficios pueden cubrir fácilmente la sobrecarga adicional.

Crear rootfs solo rootfs requiere un esfuerzo adicional para los desarrolladores integrados, y ahí es donde VFS entra en escena. Linux requiere que los archivos en /var sean editables, y además, muchas aplicaciones populares que ejecutan sistemas embebidos intentarán crear dot-files configuración en $HOME . Una de las soluciones para los archivos de configuración en el directorio de inicio suele ser su generación y ensamblaje preliminar en rootfs . Para /var uno de los enfoques posibles es montarlo en una sección separada que se pueda escribir, mientras que / mount en sí es de solo lectura. Otra alternativa popular es usar montajes de unión o superposición.

Monturas enlazables y superpuestas, su uso por contenedores

La ejecución del comando man mount es la mejor manera de aprender acerca de los montajes mapeados y superpuestos que brindan a los desarrolladores y administradores del sistema la capacidad de crear un sistema de archivos de una manera y luego proporcionarlo a las aplicaciones de otra. Para los sistemas integrados, esto significa la capacidad de almacenar archivos en /var en una unidad flash de solo lectura, pero superponer o vincular la ruta de tmpfs a /var en el arranque permitirá que las aplicaciones escriban notas allí (garabato). La próxima vez que lo habilite, los cambios en /var se perderán. Un montaje superpuesto crea una unión entre tmpfs y el sistema de archivos subyacente y le permite modificar supuestamente los archivos existentes en ro-tootf mientras que un montaje vinculado puede hacer que las nuevas carpetas tmpfs vacías sean visibles como grabables en ro-rootfs rutas de ro-rootfs . Si bien overlayfs es el tipo proper de sistema de archivos, los montajes de enlace se implementan en el espacio de nombres VFS .

Según la descripción de los montajes superpuestos y vinculados, a nadie le sorprende que los contenedores de Linux los utilicen activamente. Observemos lo que sucede cuando usamos systemd-nspawn para iniciar el contenedor con la herramienta mountsnoop .



Una llamada a system-nspawn inicia el contenedor mientras se mountsnoop.py .

Veamos que pasó:



La ejecución de mountsnoop durante el "arranque" del contenedor indica que el tiempo de ejecución del contenedor depende en gran medida del montaje que se está conectando (solo se muestra el comienzo de la salida larga).

Aquí, systemd-nspawn proporciona los archivos seleccionados en los procfs y sysfs host al contenedor como rutas a sus rootfs . Además del indicador MS_BIND , que establece el montaje de enlace, algunos otros indicadores en el sistema montado determinan la relación entre los cambios en el espacio de nombres del host y el contenedor. Por ejemplo, un montaje vinculante puede omitir los cambios en /proc y /sys en un contenedor u ocultarlos según la llamada.

Conclusión

Comprender la estructura interna de Linux puede parecer una tarea imposible, ya que el núcleo en sí contiene una gran cantidad de código, dejando a un lado las aplicaciones de espacio de usuario de Linux y las interfaces de llamada del sistema en bibliotecas C como glibc . Una forma de avanzar es leer el código fuente de un subsistema del núcleo con énfasis en comprender las llamadas y encabezados del sistema que se enfrentan al espacio del usuario, así como las principales interfaces internas del núcleo, por ejemplo, la tabla file_operations . Las operaciones de archivo proporcionan el principio de "todo es un archivo", por lo que administrarlas es especialmente agradable. Los archivos del núcleo de origen C en el directorio de nivel superior fs/ representan la implementación de sistemas de archivos virtuales, que son una capa de shell que proporciona una compatibilidad amplia y relativamente simple de los sistemas de archivos y dispositivos de almacenamiento populares. El montaje con enlace y superposición a través de espacios de nombres de Linux es la magia de VFS que hace posible crear contenedores de solo lectura y sistemas de archivos raíz. En combinación con el aprendizaje del código fuente, la herramienta básica eBPF y su interfaz bcc
hacer que la investigación de kernel sea más fácil que nunca.

Amigos, escribir este artículo fue útil para ustedes? Tal vez tienes algún comentario o comentarios? Y aquellos que estén interesados ​​en el curso de Administrador de Linux, los invitamos a la jornada de puertas abiertas , que tendrá lugar el 18 de abril.

La primera parte

Source: https://habr.com/ru/post/447748/


All Articles