¿Cómo funciona / proc / *?

62

Hay muchos archivos en /proc, como /proc/cpuinfo, /proc/meminfo, /proc/devicesetc., que, cuando se abre, la información del sistema de retorno.

Estos archivos no parecen existir en la realidad, ya que su ejecución filesolo indica que están vacíos.

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

¿Cómo funcionan exactamente estos archivos?

usuario2064000
fuente

Respuestas:

72

En realidad es bastante simple, al menos si no necesita los detalles de implementación.

En primer lugar, en Linux todos los sistemas de archivos (ext2, ext3, btrfs, reiserfs, tmpfs, zfs, ...) se implementan en el núcleo. Algunos pueden descargar el trabajo al código del país de usuario a través de FUSE, y algunos vienen solo en forma de un módulo del núcleo ( ZFS nativo es un ejemplo notable de este último debido a restricciones de licencia), pero de cualquier manera sigue siendo un componente del núcleo. Este es un básico importante.

Cuando un programa quiere leer desde un archivo, que emitirá diversas llamadas a las bibliotecas del sistema que finalmente terminan en el núcleo en forma de open(), read(), close()secuencia (posiblemente con seek()tirado en una buena medida). El núcleo toma la ruta y el nombre de archivo proporcionados, y a través del sistema de archivos y la capa de E / S del dispositivo los traduce a solicitudes de lectura física (y en muchos casos también solicitudes de escritura, piense, por ejemplo, en actualizaciones de tiempo) a algún almacenamiento subyacente.

Sin embargo, no tiene que traducir esas solicitudes específicamente al almacenamiento físico y persistente . El contrato del núcleo es que la emisión de ese conjunto particular de llamadas al sistema proporcionará el contenido del archivo en cuestión . Donde exactamente en nuestro ámbito físico existe el "archivo" es secundario a esto.

Por /proclo general, se monta lo que se conoce como procfs. Ese es un tipo de sistema de archivos especial, pero como es un sistema de archivos, realmente no es diferente de, por ejemplo, un ext3sistema de archivos montado en algún lugar. Entonces, la solicitud se pasa al código del controlador del sistema de archivos procfs, que conoce todos estos archivos y directorios y devuelve información particular de las estructuras de datos del núcleo .

La "capa de almacenamiento" en este caso son las estructuras de datos del núcleo y procfsproporciona una interfaz limpia y conveniente para acceder a ellas. Tenga en cuenta que montar procesos en /proces simplemente una convención; podrías montarlo fácilmente en otro lugar. De hecho, eso a veces se hace, por ejemplo en chroot jails cuando el proceso que se ejecuta allí necesita acceso a / proc por alguna razón.

Funciona de la misma manera si escribe un valor en algún archivo; a nivel del kernel, que se traduce en una serie de open(), seek(), write(), close()las llamadas que a su vez van pasando al controlador del sistema de archivos; de nuevo, en este caso particular, el código procfs.

La razón particular por la que ve fileregresar emptyes que muchos de los archivos expuestos por procfs están expuestos con un tamaño de 0 bytes. El tamaño de 0 bytes probablemente sea una optimización en el lado del kernel (muchos de los archivos en / proc son dinámicos y pueden variar fácilmente en longitud, posiblemente incluso de una lectura a la siguiente, y calcular la longitud de cada archivo en cada lectura de directorio sería potencialmente ser muy caro). Al seguir los comentarios a esta respuesta, que puede verificar en su propio sistema ejecutando strace o una herramienta similar, fileprimero realiza una stat()llamada para detectar cualquier archivo especial y luego aprovecha la oportunidad para, si el tamaño del archivo se informa como 0 , aborta e informa que el archivo está vacío.

Este comportamiento está realmente documentado y puede anularse especificando -so --special-filesen la fileinvocación, aunque como se indica en la página del manual que puede tener efectos secundarios. La cita a continuación es de la página del manual del archivo BSD 5.11, fechada el 17 de octubre de 2011.

Normalmente, el archivo solo intenta leer y determinar el tipo de archivos de argumentos cuyos informes stat (2) son archivos normales. Esto evita problemas, porque leer archivos especiales puede tener consecuencias peculiares. Al especificar la -sopción, el archivo también lee archivos de argumentos que son archivos especiales de bloques o caracteres. Esto es útil para determinar los tipos de datos del sistema de archivos en particiones de disco sin formato, que son archivos especiales de bloques. Esta opción también hace que el archivo ignore el tamaño del archivo según lo informado por stat (2) ya que en algunos sistemas informa un tamaño cero para particiones de disco sin formato.

un CVn
fuente
55
Cuando lo miras con strace file /proc/versiono ltrace -S /proc/version, la optimización es bastante pequeña. Primero realiza una stat()llamada y descubre que el tamaño es 0, omitiendo así open(), pero antes de eso está cargando varios archivos mágicos.
ott--
2
@ ott-- Esa sí que es una secuencia extraña de eventos, pero puede estar relacionada con el hecho de que puede pasarle múltiples nombres de archivos file. De esta manera, el archivo precarga los archivos mágicos, luego procesa la línea de comando parámetro por parámetro; en lugar de mover el archivo mágico al "hacer esto justo antes de tratar de determinar qué tipo de archivo es este ", parte del código, lo que aumentaría la complejidad. Llamar stat()y actuar sobre su valor de retorno es esencialmente inofensivo; agregando complejidad para realizar un seguimiento de los riesgos de estado interno adicionales que introducen errores.
un CVn
@ ott-- En realidad, el motivo por el cual el file"archivo está vacío" es porque llama stata detectar archivos especiales (tuberías con nombre, dispositivos, ...), y aprovecha esta oportunidad para detener el procesamiento de archivos vacíos. file -s /proc/versioninforma "texto ASCII".
Gilles 'SO- deja de ser malvado'
44
@Gilles The -sse supone para dispositivos especiales block / char. Finalmente miré la filefuente, y al final de fsmagic.c vi esta explicación por qué regresa en ASCII textlugar de empty:If stat() tells us the file has zero length, report here that the file is empty, so we can skip all the work of opening and reading the file. But if the -s option has been given, we skip this optimization, since on some systems, stat() reports zero size for raw disk partitions.
ott--
15

En este directorio, puede controlar cómo el kernel ve los dispositivos, ajustar la configuración del kernel, agregar dispositivos al kernel y eliminarlos nuevamente. En este directorio puede ver directamente el uso de memoria y las estadísticas de E / S.

Puede ver qué discos están montados y qué sistemas de archivos se utilizan. En resumen, cada aspecto de su sistema Linux puede examinarse desde este directorio, si sabe qué buscar.

El /procdirectorio no es un directorio normal. Si tuviera que arrancar desde un CD de arranque y mirara ese directorio en su disco duro, lo vería vacío. Cuando lo miras bajo tu sistema de funcionamiento normal, puede ser bastante grande. Sin embargo, no parece estar utilizando ningún espacio en el disco duro. Esto se debe a que es un sistema de archivos virtual.

Dado que el /procsistema de archivos es un sistema de archivos virtual y reside en la memoria, /procse crea un nuevo sistema de archivos cada vez que se reinicia su máquina Linux.

En otras palabras, es solo un medio para echar un vistazo y hurgar en las entrañas del sistema Linux a través de una interfaz de tipo de archivo y directorio. Cuando mira un archivo en el /procdirectorio, está mirando directamente un rango de memoria en el kernel de Linux y viendo lo que puede ver.

Las capas en el sistema de archivos.

Ingrese la descripción de la imagen aquí

Ejemplos:

  • En el interior /proc, hay un directorio para cada proceso en ejecución, nombrado con su ID de proceso. Estos directorios contienen archivos que tienen información útil sobre los procesos, como:
    • exe: que es un enlace simbólico al archivo en el disco desde el que se inició el proceso.
    • cwd: que es un enlace simbólico al directorio de trabajo del proceso.
    • wchan: que, cuando se lee, devuelve el canal de espera en el que se encuentra el proceso.
    • maps: que, cuando se lee, devuelve los mapas de memoria del proceso.
  • /proc/uptime devuelve el tiempo de actividad como dos valores decimales en segundos, separados por un espacio:
    • la cantidad de tiempo desde que se inició el núcleo.
    • La cantidad de tiempo que el núcleo ha estado inactivo.
  • /proc/interrupts: Para información relacionada con interrupciones.
  • /proc/modules: Para una lista de módulos.

Para obtener información más detallada, consulte man proc o kernel.org .

stderr
fuente
"Si tuviera que arrancar desde un CD de arranque y mirara ese directorio en su disco duro, lo vería vacío". Eso no es específico de / proc, es general para cualquier punto de montaje donde el sistema de archivos subyacente no se haya montado. Si arranca desde el mismo CD de arranque y hace algo así mount -t procfs procfs /mnt/proc, verá el kernel / proc actualmente en ejecución.
un CVn
5

Estás en lo correcto, no son archivos reales.

En términos más simples, es una forma de hablar con el kernel utilizando los métodos normales de lectura y escritura de archivos, en lugar de llamar al kernel directamente. Está en línea con la filosofía de "todo es un archivo" de Unix.

Los archivos /procno existen físicamente en ninguna parte, pero el núcleo reacciona a los archivos que lee y escribe allí, y en lugar de escribir en el almacenamiento, informa información o hace algo.

Del mismo modo, los archivos /devno son realmente archivos en el sentido tradicional (aunque en algunos sistemas los archivos en /devrealidad pueden existir en el disco, no tendrán mucho más que el dispositivo al que se refieren): le permiten hablar a un dispositivo que usa la API normal de E / S de archivos Unix, o cualquier cosa que lo use, como shells

LawrenceC
fuente
1
Es más como * nix que solo se puede proteger un archivo. Dado que las listas de control de acceso persisten en el sistema de archivos, es conveniente asegurar los recursos privilegiados utilizando el mecanismo común que ya proporciona el controlador del sistema de archivos. Esto simplifica la implementación de herramientas que acceden a las estructuras del núcleo y les permite ejecutarse sin permisos elevados al leer en su lugar los archivos virtuales del sistema de archivos proc.
Pekka
3

Dentro del /procdirectorio, hay dos tipos de contenido, el primer directorio numerado y el segundo es el archivo de información del sistema.

/proces un sistema de archivos virtual Por ejemplo, si lo hace ls -l /proc/stat, notará que tiene un tamaño de 0 bytes, pero si hace “cat / proc / stat”, verá algo de contenido dentro del archivo.

Haga un ls -l /proc, y verá muchos directorios con solo números. Estos números representan los ID de proceso (PID). Los archivos dentro de este directorio numerado corresponden al proceso con ese PID particular.

Algunos archivos que están disponibles en /proc, contienen información del sistema como cpuinfo, meminfo y loadavg.

Algunos comandos de Linux leen la información de estos /procarchivos y la muestran. Por ejemplo, el comando gratuito lee la información de la memoria del /proc/meminfoarchivo, la formatea y la muestra.

Para obtener más información sobre los /procarchivos individuales , haga "man 5 FILENAME".

/proc/cmdline – Kernel command line
/proc/cpuinfo – Information about the processors.
/proc/devices – List of device drivers configured into the currently running kernel.
/proc/dma – Shows which DMA channels are being used at the moment.
/proc/fb – Frame Buffer devices.
/proc/filesystems – File systems supported by the kernel.
/proc/interrupts – Number of interrupts per IRQ on architecture.
/proc/iomem – This file shows the current map of the system’s memory for its various devices
/proc/ioports – provides a list of currently registered port regions used for input or output communication with a device
/proc/loadavg – Contains load average of the system
The first three columns measure CPU utilization of the last 1, 5, and 10 minute periods.
The fourth column shows the number of currently running processes and the total number of processes.
The last column displays the last process ID used.
/proc/locks – Displays the files currently locked by the kernel
Sample line:
1: POSIX ADVISORY WRITE 14375 08:03:114727 0 EOF
/proc/meminfo – Current utilization of primary memory on the system
/proc/misc – This file lists miscellaneous drivers registered on the miscellaneous major device, which is number 10
/proc/modules – Displays a list of all modules that have been loaded by the system
/proc/mounts – This file provides a quick list of all mounts in use by the system
/proc/partitions – Very detailed information on the various partitions currently available to the system
/proc/pci – Full listing of every PCI device on your system
/proc/stat – Keeps track of a variety of different statistics about the system since it was last restarted
/proc/swap – Measures swap space and its utilization
/proc/uptime – Contains information about uptime of the system
/proc/version – Version of the Linux kernel, gcc, name of the Linux flavor installed.
Shailesh
fuente
2
Esto me suena más como "¿cómo usar lo que está en / proc?" en lugar de "¿cómo funciona / proc?". Información útil, pero no necesariamente responde a esta pregunta en particular .
un CVn
Cada archivo en / proc es información de tiempo de ejecución, lo que significa que cuando cat / proc / meminfo parte del núcleo ejecuta una función que genera el contenido del archivo.
Shailesh
3

Ejemplo ejecutable mínimo

La mejor manera de entender estas cosas en mi opinión es jugar con ellas, así que aquí hay un módulo de kernel que crea una entrada procfs:

myprocfs.c

#include <linux/debugfs.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h> /* seq_read, seq_lseek, single_open, single_release */
#include <uapi/linux/stat.h> /* S_IRUSR */

static const char *filename = "lkmc_procfs";

static int show(struct seq_file *m, void *v)
{
    seq_printf(m, "abcd\n");
    return 0;
}

static int open(struct inode *inode, struct  file *file)
{
    return single_open(file, show, NULL);
}

static const struct file_operations fops = {
    .llseek = seq_lseek,
    .open = open,
    .owner = THIS_MODULE,
    .read = seq_read,
    .release = single_release,
};

static int myinit(void)
{
    proc_create(filename, 0, NULL, &fops);
    return 0;
}

static void myexit(void)
{
    remove_proc_entry(filename, NULL);
}

module_init(myinit)
module_exit(myexit)
MODULE_LICENSE("GPL");

y luego interactuamos con él como:

insmod procfs.ko
cat /proc/lkmc_procfs

y eso produce la salida:

abcd

A partir de este ejemplo, vemos claramente que los procarchivos nos permiten implementar "llamadas al sistema relacionadas con archivos" arbitrarias como open, ready llseek.

Esas llamadas al sistema se pueden usar para una comunicación arbitraria con el núcleo.

Por lo tanto, esos archivos no necesitan tener nada que ver con los archivos reales en los sistemas de archivos, y ese es el caso para casi todos.

En nuestro pequeño ejemplo, por ejemplo, simplemente hacemos un archivo inútil para el que readsiempre regresa abcd\n.

Aquí está mi configuración de QEMU + Buildroot totalmente automatizada para construir y jugar de manera fácil y segura con este módulo de kernel:

Algunas otras interfaces similares incluyen:

Ciro Santilli 新疆 改造 中心 法轮功 六四 事件
fuente