Esta es una pregunta de bajo nivel, y entiendo que podría no ser el mejor lugar para preguntar. Pero, parecía más apropiado que cualquier otro sitio de SE, así que aquí va.
Sé que en el sistema de archivos de Linux, algunos archivos realmente existen , por ejemplo: /usr/bin/bash
es uno que existe. Sin embargo, (por lo que yo entiendo), algunos también no existen realmente como tales y son más virtuales archivos, por ejemplo: /dev/sda
, /proc/cpuinfo
, etc. Mis preguntas son (son dos, pero demasiado estrechamente relacionados que ser preguntas separadas):
- ¿Cómo funciona el kernel de Linux si estos archivos son reales (y, por lo tanto, los leen del disco) o no cuando se emite un comando de lectura (o tal)?
- Si el archivo no es real: como ejemplo, una lectura de
/dev/random
devolverá datos aleatorios, y una lectura de/dev/null
devolveráEOF
. ¿Cómo funciona qué datos leer de este archivo virtual? o incluso para el directorio virtual en sí? Entonces, una entrada para/dev/null
simplemente podría devolver unEOF
.
Respuestas:
Así que aquí hay básicamente dos tipos diferentes de cosas:
/proc
y/sys
son ejemplos aquí, como son los sistemas de archivos personalizados FUSE comosshfs
oifuse
. Hay mucha más diversidad en estos, porque en realidad solo se refieren a un sistema de archivos con semántica que en cierto sentido son "personalizados". Por lo tanto, cuando lee de un archivo debajo/proc
, en realidad no está accediendo a un dato específico que ha sido almacenado por otra cosa que lo escribió anteriormente, como en un sistema de archivos normal. Básicamente, está haciendo una llamada de kernel, solicitando información que se genera sobre la marcha. Y este código puede hacer lo que quiera, ya que es solo una función en algún lugar que implementaread
semántica. Por lo tanto, tiene el comportamiento extraño de los archivos/proc
, como por ejemplo pretender ser enlaces simbólicos cuando no estánLa clave es que
/dev
, en realidad, suele ser una de las primeras. Es normal en las distribuciones modernas tener/dev
algo así como un tmpfs, pero en los sistemas más antiguos, era normal tener un directorio plano en el disco, sin ningún atributo especial. La clave es que los archivos bajo/dev
encuentran son nodos de dispositivo, un tipo de archivo especial similar a los sockets FIFO o Unix; un nodo de dispositivo tiene un número mayor y menor, y leerlos o escribirlos está llamando a un controlador de kernel, al igual que leer o escribir un FIFO está llamando al kernel para almacenar su salida en una tubería. Este controlador puede hacer lo que quiera, pero generalmente toca el hardware de alguna manera, por ejemplo, para acceder a un disco duro o reproducir sonido en los altavoces.Para responder las preguntas originales:
Hay dos preguntas relevantes sobre si el 'archivo existe' o no; estos son si el archivo de nodo del dispositivo existe literalmente y si el código del núcleo que lo respalda es significativo. El primero se resuelve como cualquier cosa en un sistema de archivos normal. Los sistemas modernos usan
udev
o algo similar para observar eventos de hardware y crear y destruir automáticamente los nodos del dispositivo en/dev
consecuencia. Pero los sistemas más antiguos, o las compilaciones personalizadas livianas, pueden tener todos sus nodos de dispositivo literalmente en el disco, creados con anticipación. Mientras tanto, cuando lee estos archivos, está haciendo una llamada al código del núcleo que está determinado por los números de dispositivo mayor y menor; Si no son razonables (por ejemplo, está tratando de leer un dispositivo de bloqueo que no existe), obtendrá algún tipo de error de E / S.La forma en que funciona qué código del kernel llamar para qué archivo de dispositivo varía. Para sistemas de archivos virtuales como
/proc
, implementan sus propiosread
ywrite
funciones; el núcleo solo llama a ese código según el punto de montaje en el que se encuentre, y la implementación del sistema de archivos se encarga del resto. Para los archivos del dispositivo, se envía en función de los números de dispositivo mayor y menor.fuente
/dev
aún estarían allí, pero supongo que se borrarían cuando se inicie el sistema.tmpfs
los crearía y eliminaría dinámicamente según sea necesario, por ejemplo: ¿arranque y apagado?devtmpfs
, el/dev
sistema de archivos en Linux moderno, es similar a atmpfs
, pero tiene algunas diferencias que soportarudev
. (El kernel crea algunos nodos automatizados por sí solo antes de entregarlosudev
, para que el arranque sea menos complicado). En todos estos casos, los nodos de dispositivos viven solo en la RAM y se crean y destruyen dinámicamente según lo requiera el hardware. Presumiblemente, también podría usarloudev
en un disco ordinario/dev
, pero nunca he visto esto hecho y no parece haber buenas razones para hacerlo.Aquí hay una lista de archivos de
/dev/sda1
mi servidor Arch Linux casi actualizado:Entonces, la entrada del directorio
/dev/
parasda
tiene un número de inodo, 1294. Es un archivo real en el disco.Mire dónde aparece generalmente el tamaño del archivo. "8, 1" aparece en su lugar. Este es un número de dispositivo mayor y menor. También tenga en cuenta la 'b' en los permisos de archivo.
El archivo
/usr/include/ext2fs/ext2_fs.h
contiene esta estructura (fragmento) C:Esa estructura nos muestra la estructura en disco del inodo de un archivo. Hay muchas cosas interesantes en esa estructura; échale un vistazo largo.
El
i_mode
elemento destruct ext2_inode
tiene 16 bits, y usa solo 9 para los permisos de usuario / grupo / otro, lectura / escritura / ejecución, y otros 3 para setuid, setgid y sticky. Tiene 4 bits para diferenciar entre tipos como "archivo plano", "enlace", "directorio", "canalización con nombre", "socket de la familia Unix" y "dispositivo de bloque".El kernel de Linux puede seguir el algoritmo de búsqueda de directorio habitual, luego tomar una decisión basada en los permisos y las marcas en el
i_mode
elemento. Para 'b', bloquear archivos de dispositivo, puede encontrar los números de dispositivo mayor y menor, y tradicionalmente, usar el número de dispositivo principal para buscar un puntero a alguna función del núcleo (un controlador de dispositivo) que se ocupa de discos. El número de dispositivo menor generalmente se usa como, por ejemplo, el número de dispositivo del bus SCSI, o el número de dispositivo EIDE o algo así.Algunas otras decisiones sobre cómo tratar un archivo como
/proc/cpuinfo
se toman en función del tipo de sistema de archivos. Si haces un:puede ver que
/proc
tiene un tipo de sistema de archivos de "proc". La lectura de un archivo/proc
hace que el kernel haga algo diferente según el tipo de sistema de archivos, al igual que abrir un archivo en un sistema de archivos ReiserFS o DOS podría hacer que el kernel use diferentes funciones para ubicar archivos y localizar datos del archivosfuente
4026531975 -r--r--r-- 1 root root 0 Nov 14 18:41 /proc/mdstat
que claramente no es un "archivo real".Al final del día, todos son archivos para Unix, esa es la belleza de la abstracción.
La forma en que el núcleo maneja los archivos, ahora que es una historia diferente.
/ proc y hoy en día / dev y / run (también conocido como / var / run) son sistemas de archivos virtuales en RAM. / proc es una interfaz / windows para kernel variables y estructuras.
Recomiendo leer The Linux Kernel http://tldp.org/LDP/tlk/tlk.html y controladores de dispositivos Linux, tercera edición https://lwn.net/Kernel/LDD3/ .
También disfruté el diseño e implementación del sistema operativo FreeBSD http://www.amazon.com/Design-Implementation-FreeBSD-Operating-System/dp/0321968972/ref=sr_1_1
Eche un vistazo a la página relevante que pertenece a su pregunta.
http://www.tldp.org/LDP/tlk/dd/drivers.html
fuente
Además de las respuestas de @ RuiFRibeiro y @ BruceEdiger, la distinción que usted hace no es exactamente la distinción que hace el núcleo. En realidad, tiene varios tipos de archivos: archivos normales, directorios, enlaces simbólicos, dispositivos, sockets (y siempre olvido algunos, así que no intentaré hacer una lista completa). Puede tener la información sobre el tipo de archivo con
ls
: es el primer carácter de la línea. Por ejemplo:La 'b' al principio indica que este archivo es un dispositivo de bloque. Un guión significa un archivo normal, 'l', un enlace simbólico, etc. Esta información se almacena en los metadatos del archivo y es accesible a través de la llamada del sistema
stat
por ejemplo, se puede , por lo que el núcleo puede leer de manera diferente un archivo y un enlace simbólico, por ejemplo.Luego, hace otra distinción entre "archivos reales"
/bin/bash
y "archivos virtuales",/proc/cpuinfo
perols
informa ambos como archivos normales, por lo que la diferencia es de otro tipo:Lo que sucede es que pertenecen a diferentes sistemas de archivos.
/proc
es el punto de montaje de un pseudo-sistema de archivosprocfs
mientras/bin/bash
está en un sistema de archivos de disco normal. Cuando Linux abre un archivo (lo hace de manera diferente según el sistema de archivos), llena una estructura de datosfile
que tiene, entre otros atributos, una estructura de varios punteros de función que describen cómo usar este archivo. Por lo tanto, puede implementar comportamientos distintos para diferentes tipos de archivos.Por ejemplo, estas son las operaciones anunciadas por
/proc/meminfo
:Si observa la definición de
meminfo_proc_open
, puede ver que esta función llena un búfer en la memoria con la información devuelta por la funciónmeminfo_proc_show
, cuya tarea es recopilar datos sobre el uso de la memoria. Esta información se puede leer normalmente. Cada vez que abre el archivo,meminfo_proc_open
se llama a la función y se actualiza la información sobre la memoria.fuente
Todos los archivos en un sistema de archivos son "reales" en el sentido de que permiten E / S de archivos. Cuando abre un archivo, el núcleo crea un descriptor de archivo, que es un objeto (en el sentido de la programación orientada a objetos) que actúa como un archivo. Si lee el archivo, el descriptor de archivo ejecuta su método de lectura, que a su vez solicitará al sistema de archivos (sysfs, ext4, nfs, etc.) datos del archivo. Los sistemas de archivos presentan una interfaz uniforme para el espacio de usuario y saben qué hacer para manejar lecturas y escrituras. Los sistemas de archivos a su vez solicitan a otras capas que manejen sus solicitudes. Para un archivo normal en digamos un sistema de archivos ext4, esto implicará búsquedas en las estructuras de datos del sistema de archivos (que pueden incluir lecturas de disco) y, finalmente, una lectura del disco (o caché) para copiar datos en el búfer de lectura. Para un archivo en say sysfs, generalmente solo sprintf () s algo al búfer. Para un nodo de desarrollo de bloque, le pedirá al controlador de disco que lea algunos bloques y los copie en el búfer (los números mayor y menor le indican al sistema de archivos a qué controlador debe realizar las solicitudes).
fuente