¿Qué sucede cuando ejecuto el comando cat / proc / cpuinfo?

Respuestas:

72

Cada vez que lee un archivo debajo /proc, esto invoca un código en el núcleo que calcula el texto para leerlo como contenido del archivo. El hecho de que el contenido se genere sobre la marcha explica por qué casi todos los archivos tienen su tiempo reportado como ahora y su tamaño reportado como 0; aquí debería leer 0 como "no sé". A diferencia de los sistemas de archivos habituales, el sistema de archivos que está montado /proc, que se llama procfs , no carga datos desde un disco u otro medio de almacenamiento (como FAT, ext2, zfs, ...) o sobre la red (como NFS, Samba, ...) y no llama al código de usuario (a diferencia de FUSE ).

Procfs está presente en la mayoría de las unidades no BSD. Comenzó su vida en los Bell Labs de AT&T en la 8ª edición de UNIX como una forma de informar información sobre procesos (y a psmenudo es una bonita impresora para leer la información /proc). La mayoría de las implementaciones de procfs tienen un archivo o directorio llamado /proc/123para informar información sobre el proceso con PID 123. Linux extiende el sistema de archivos proc con muchas más entradas que informan el estado del sistema, incluido su ejemplo /proc/cpuinfo.

En el pasado, Linux /procadquirió varios archivos que proporcionan información sobre los controladores, pero este uso ahora está en desuso /sysy /procahora evoluciona lentamente. Las entradas les gusta /proc/busy /proc/fs/ext4permanecen donde están para la compatibilidad con versiones anteriores, pero se crean interfaces similares más nuevas /sys. En esta respuesta, me enfocaré en Linux.

Sus primeros y segundos puntos de entrada para la documentación sobre /procLinux son:

  1. la proc(5)página man ;
  2. El /procsistema de archivos en la documentación del núcleo .

Su tercer punto de entrada, cuando la documentación no lo cubre, es leer la fuente . Puede descargar la fuente en su máquina, pero este es un gran programa, y LXR , la referencia cruzada de Linux, es de gran ayuda. (Hay muchas variantes de LXR; la que se está ejecutando lxr.linux.noes, con mucho, la mejor, pero desafortunadamente el sitio a menudo está caído.) Se requiere un poco de conocimiento de C, pero no es necesario ser un programador para rastrear un valor misterioso .

El manejo principal de las /procentradas está en el fs/procdirectorio. Cualquier controlador puede registrar entradas en /proc(aunque, como se indicó anteriormente, esto ahora está en desuso /sys), por lo que si no encuentra lo que está buscando fs/proc, busque en cualquier otro lugar. Los controladores llaman a las funciones declaradas en include/linux/proc_fs.h. Las versiones de kernel hasta 3.9 proporcionan las funciones create_proc_entryy algunos contenedores (especialmente create_proc_read_entry), y las versiones de kernel 3.10 y superiores proporcionan solo en su lugar proc_createy proc_create_data(y algunas más).

Tomando /proc/cpuinfocomo ejemplo, una búsqueda de la "cpuinfo"que conduce a la llamada a proc_create("cpuinfo, …")en fs/proc/cpuinfo.c. Puede ver que el código es prácticamente un código repetitivo: dado que la mayoría de los archivos /procsimplemente descargan algunos datos de texto, hay funciones auxiliares para hacerlo. Simplemente hay una seq_operationsestructura, y la verdadera carne está en la cpuinfo_opestructura de datos, que depende de la arquitectura, generalmente definida en arch/<architecture>/kernel/setup.c(o a veces en un archivo diferente). Tomando x86 como ejemplo, nos conducen a arch/x86/kernel/cpu/proc.c. Allí la función principal esshow_cpuinfo, que imprime el contenido del archivo deseado; el resto de la infraestructura está ahí para alimentar los datos al proceso de lectura a la velocidad que lo solicita. Puede ver los datos que se ensamblan sobre la marcha a partir de datos en varias variables en el núcleo, incluidos algunos números calculados sobre la marcha, como la frecuencia de la CPU .

Una gran parte /proces la información por proceso en /proc/<PID>. Estas entradas están registradas en fs/proc/base.c, en la tgid_base_stuffmatriz ; Algunas funciones registradas aquí se definen en otros archivos. Veamos algunos ejemplos de cómo se generan estas entradas:

  • cmdlinees generado por proc_pid_cmdlineen el mismo archivo. Localiza los datos en el proceso y los imprime.
  • clear_refs, a diferencia de las entradas que hemos visto hasta ahora, es grabable pero no legible. Por lo tanto, las proc_clear_refs_operationsestructuras definen una clear_refs_writefunción pero no una función de lectura.
  • cwdes un enlace simbólico (un poco mágico), declarado por proc_cwd_link, que busca el directorio actual del proceso y lo devuelve como el contenido del enlace.
  • fdEs un subdirectorio. Las operaciones en el directorio en sí están definidas en la proc_fd_operationsestructura de datos (son repetitivas excepto por la función que enumera las entradas proc_readfd, que enumera los archivos abiertos del proceso) mientras que las operaciones en las entradas están en `proc_fd_inode_operations .

Otra área importante de /proces /proc/sys, que es una interfaz directa para sysctl. La lectura de una entrada en esta jerarquía devuelve el valor del valor sysctl correspondiente, y la escritura establece el valor sysctl. Los puntos de entrada para sysctl están en fs/proc/proc_sysctl.c. Los sistemas tienen su propio sistema de registro con register_sysctly amigos.

Gilles
fuente
59

Cuando intentas obtener una idea de qué tipo de magia está sucediendo detrás de escena, tu mejor amigo es strace. Aprender a operar esta herramienta es una de las mejores cosas que puedes hacer para apreciar mejor la magia loca que está sucediendo detrás de escena.

$ strace -s 200 -m strace.log cat /proc/cpuinfo
...
read(3, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU       M 560  @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 65536) = 3464
write(1, "processor\t: 0\nvendor_id\t: GenuineIntel\ncpu family\t: 6\nmodel\t\t: 37\nmodel name\t: Intel(R) Core(TM) i5 CPU       M 560  @ 2.67GHz\nstepping\t: 5\nmicrocode\t: 0x4\ncpu MHz\t\t: 1199.000\ncache size\t: 3072 KB\nphy"..., 3464) = 3464
read(3, "", 65536)                      = 0
close(3)                                = 0
...

En el resultado anterior, puede ver que /proc/cpuinfoes solo un archivo normal, o al menos parece ser uno. Así que profundicemos más.

Inmersión más profunda

# 1 - con ls ..

Mirando el archivo en sí, parecería ser "solo un archivo".

$ ls -l /proc/cpuinfo 
-r--r--r--. 1 root root 0 Mar 26 22:45 /proc/cpuinfo

Pero mira más de cerca. Obtenemos nuestra primera pista de que es especial, tenga en cuenta que el tamaño del archivo es de 0 bytes.

# 2 - con estadísticas

Si ahora miramos el archivo usando stat, podemos obtener nuestra siguiente pista de que hay algo especial en esto /proc/cpuinfo.

ejecutar # 1
$ stat /proc/cpuinfo 
  File: ‘/proc/cpuinfo’
  Size: 0           Blocks: 0          IO Block: 1024   regular empty file
Device: 3h/3dInode: 4026532023  Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:18.390753719 -0400
Modify: 2014-03-26 22:46:18.390753719 -0400
Change: 2014-03-26 22:46:18.390753719 -0400
 Birth: -
ejecutar # 2
$ stat /proc/cpuinfo 
  File: ‘/proc/cpuinfo’
  Size: 0           Blocks: 0          IO Block: 1024   regular empty file
Device: 3h/3dInode: 4026532023  Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Context: system_u:object_r:proc_t:s0
Access: 2014-03-26 22:46:19.945753704 -0400
Modify: 2014-03-26 22:46:19.945753704 -0400
Change: 2014-03-26 22:46:19.945753704 -0400
 Birth: -

¿Observe los tiempos de acceso, modificación y cambio? Siguen cambiando para cada acceso. Esto es muy inusual que los 3 cambiarían así. A menos que se editen, los atributos de marca de tiempo de un archivo generalmente permanecen igual.

# 3 - con archivo ..

Otra pista más de que este archivo es cualquier cosa menos un archivo normal:

$ file /proc/cpuinfo 
/proc/cpuinfo: empty

Si fuera una manifestación de una tubería con nombre, se vería similar a uno de estos archivos:

$ ls -l /dev/initctl /dev/zero 
prw-------. 1 root root    0 Mar 26 20:09 /dev/initctl
crw-rw-rw-. 1 root root 1, 5 Mar 27 00:39 /dev/zero

$ file /dev/initctl /dev/zero 
/dev/initctl: fifo (named pipe)
/dev/zero:    character special

Si tocamos un emptyfile, /proc/cpuinfoparece ser más como un archivo que una tubería:

$ touch emptyfile
$ ls -l emptyfile 
-rw-rw-r--. 1 saml saml 0 Mar 27 07:40 emptyfile
$ file emptyfile 
emptyfile: empty
# 4 - con montura ..

Entonces, en este punto, debemos dar un paso atrás y alejarnos un poco. Estamos viendo un archivo en particular, pero quizás deberíamos estar mirando el sistema de archivos en el que reside este archivo. Y para esto podemos usar el mountcomando.

$ mount | grep " /proc "
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)

OK, entonces el tipo de sistema de archivos es de tipo proc. Por /proclo tanto, es un tipo de sistema de archivos diferente, esa es nuestra sugerencia de que los archivos debajo /procson especiales. No son solo sus archivos de ejecución. Entonces, descubramos más información sobre lo que hace que el procsistema de archivos sea especial.

Echando un vistazo a mountla página del manual de:

El sistema de archivos proc no está asociado con un dispositivo especial y, al montarlo, se puede usar una palabra clave arbitraria, como proc, en lugar de una especificación de dispositivo. (La opción habitual none es menos afortunada: el mensaje de error 'none busy' de umount puede ser confuso).

Y si echamos un vistazo a procla página man de:

El sistema de archivos proc es un sistema de pseudoarchivos que se utiliza como interfaz para las estructuras de datos del kernel. Se suele montar en / proc. La mayor parte es de solo lectura, pero algunos archivos permiten cambiar las variables del núcleo.

Un poco más abajo en esa misma página de manual:

/ proc / cpuinfo

Esta es una colección de elementos dependientes de la CPU y la arquitectura del sistema, para cada arquitectura compatible una lista diferente. Dos entradas comunes son procesador que da el número de CPU y bogomips; Una constante del sistema que se calcula durante la inicialización del núcleo. Las máquinas SMP tienen información para cada CPU. El comando lscpu (1) recopila su información de este archivo.

En la parte inferior de la página del manual hay una referencia a un documento del núcleo que puede encontrar aquí, titulado: THE / proc FILESYSTEM . Citando de ese documento:

El sistema de archivos proc actúa como una interfaz para las estructuras de datos internas en el núcleo. Se puede usar para obtener información sobre el sistema y para cambiar ciertos parámetros del kernel en tiempo de ejecución (sysctl).

Conclusiones

Entonces, ¿qué aprendimos aquí? Bien dado que /procse conoce como un pseudo sistema de archivos y también como una "interfaz para estructuras de datos internas", es seguro asumir que los elementos dentro de él no son archivos reales, sino simplemente manifestaciones hechas para parecerse a archivos, pero realmente no lo son.

Terminaré con esta cita que aparentemente solía estar en una versión anterior man 5 procde alrededor de 2004, pero por alguna razón ya no está incluida. NOTA: No estoy seguro de por qué se eliminó, ya que describe muy bien lo que /proces:

El directorio / proc en los sistemas GNU / Linux proporciona una interfaz similar al sistema de archivos para el núcleo. Esto permite que las aplicaciones y los usuarios obtengan información y establezcan valores en el núcleo utilizando la operación normal de E / S del sistema de archivos.

El sistema de archivos proc a veces se denomina sistema de pseudoarchivo de información de proceso. No contiene archivos `` reales '' sino más bien información del sistema en tiempo de ejecución (por ejemplo, memoria del sistema, dispositivos montados, configuración de hardware, etc.). Por esta razón, puede considerarse como un centro de control e información para el núcleo. De hecho, muchas utilidades del sistema son simplemente llamadas a archivos en este directorio. Por ejemplo, el comando lsmod, que enumera los módulos cargados por el núcleo, es básicamente el mismo que 'cat / proc / modules', mientras que lspci, que enumera los dispositivos conectados al bus PCI del sistema, es el mismo que 'cat / proc / pci '. Al alterar los archivos ubicados en este directorio, puede cambiar los parámetros del kernel mientras el sistema se está ejecutando.

Fuente: El pseudo sistema de archivos proc

Referencias

slm
fuente
1
Genial, :) esto es lo primero que probé cuando vi la pregunta:strace -o catcpuproc.txt cat /proc/cpuinfo
mkc
1
¡Buena respuesta! En Linux, si desea profundizar, la fuente para el sistema de archivos proc está en fs / proc en la fuente del núcleo. Verá que hay un fs / proc / cpuinfo.c pero, desafortunadamente, está bastante vacío ya que el trabajo pesado se extiende por todo el arco / ya que depende de la arquitectura. Para un ejemplo más simple, vea fs / proc / uptime.c. Al echar un vistazo al archivo, podemos adivinar que uptime_proc_show es el caballo de batalla de lo que nos da los datos que queremos y podríamos explorarlos más al sumergirnos en las funciones que llama. Para comprender la interfaz seq_file y cómo se usa en procfs, consulte:
Steven D
1
@slm: +1, gran respuesta. Pero para mí, la primera pista de que es un archivo especial es su tamaño ^^ 0 bytes, sin embargo, puede capturar muchas cosas de él (un poco como algunos archivos de tubería).
Olivier Dulac
@ OlivierDulac - buen punto. He realizado modificaciones adicionales en función de sus comentarios. LMK si puedo hacer más mejoras. Gracias.
slm
14

La respuesta dada por @slm es muy completa, pero creo que una explicación más simple podría provenir de un cambio de perspectiva.

En el uso diario, podemos pensar en los archivos como cosas físicas, es decir. fragmentos de datos almacenados en algún dispositivo. Esto hace que archivos como / proc / cpuinfo sean muy misteriosos y confusos. Sin embargo, todo tiene mucho sentido si pensamos en los archivos como una interfaz ; Una forma de enviar datos dentro y fuera de algún programa.

Los programas que envían y reciben datos de esta manera son sistemas de archivos o controladores (dependiendo de cómo defina estos términos, puede ser una definición demasiado amplia o demasiado estrecha). El punto importante es que algunos de estos programas usan un dispositivo de hardware para almacenar y recuperar los datos enviados a través de esta interfaz; pero no todos.

Algunos ejemplos de sistemas de archivos que no usan un dispositivo de almacenamiento (al menos directamente) son:

  • Sistemas de archivos que utilizan datos buscados o calculados. Proc es un ejemplo, ya que obtiene datos de varios módulos del núcleo. Un ejemplo extremo es πfs (github.com/philipl/pifs)
  • Todos los sistemas de archivos FUSE, que manejan los datos con un programa de espacio de usuario normal
  • Sistemas de archivos que transforman los datos de otro sistema de archivos sobre la marcha, por ejemplo, mediante cifrado, compresión o incluso transcodificación de audio (khenriks.github.io/mp3fs/)

El sistema operativo Plan9 ( http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs ) es un ejemplo extremo de uso de archivos como una interfaz de programación general.

Warbo
fuente