¿Qué pasa cuando escribo cat /proc/cpuinfo
? ¿Es esa una canalización con nombre (o algo más) para el sistema operativo que lee la información de la CPU sobre la marcha y genera ese texto cada vez que lo llamo?
¿Qué pasa cuando escribo cat /proc/cpuinfo
? ¿Es esa una canalización con nombre (o algo más) para el sistema operativo que lee la información de la CPU sobre la marcha y genera ese texto cada vez que lo llamo?
Respuestas:
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 ps
menudo 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/123
para 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 /proc
adquirió varios archivos que proporcionan información sobre los controladores, pero este uso ahora está en desuso /sys
y /proc
ahora evoluciona lentamente. Las entradas les gusta /proc/bus
y /proc/fs/ext4
permanecen 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 /proc
Linux son:
proc(5)
página man ;/proc
sistema 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.no
es, 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 /proc
entradas está en el fs/proc
directorio. 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_entry
y algunos contenedores (especialmente create_proc_read_entry
), y las versiones de kernel 3.10 y superiores proporcionan solo en su lugar proc_create
y proc_create_data
(y algunas más).
Tomando /proc/cpuinfo
como 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 /proc
simplemente descargan algunos datos de texto, hay funciones auxiliares para hacerlo. Simplemente hay una seq_operations
estructura, y la verdadera carne está en la cpuinfo_op
estructura 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 /proc
es la información por proceso en /proc/<PID>
. Estas entradas están registradas en fs/proc/base.c
, en la tgid_base_stuff
matriz ; Algunas funciones registradas aquí se definen en otros archivos. Veamos algunos ejemplos de cómo se generan estas entradas:
cmdline
es generado por proc_pid_cmdline
en 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_operations
estructuras definen una clear_refs_write
función pero no una función de lectura.cwd
es 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.fd
Es un subdirectorio. Las operaciones en el directorio en sí están definidas en la proc_fd_operations
estructura 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 /proc
es /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_sysctl
y amigos.
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/cpuinfo
es solo un archivo normal, o al menos parece ser uno. Así que profundicemos más.
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ísticasSi ahora miramos el archivo usando stat
, podemos obtener nuestra siguiente pista de que hay algo especial en esto /proc/cpuinfo
.
$ 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/cpuinfo
parece 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 mount
comando.
$ 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 /proc
lo tanto, es un tipo de sistema de archivos diferente, esa es nuestra sugerencia de que los archivos debajo /proc
son especiales. No son solo sus archivos de ejecución. Entonces, descubramos más información sobre lo que hace que el proc
sistema de archivos sea especial.
Echando un vistazo a mount
la 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 proc
la 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).
Entonces, ¿qué aprendimos aquí? Bien dado que /proc
se 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 proc
de 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 /proc
es:
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
strace -o catcpuproc.txt cat /proc/cpuinfo
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:
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.