Así que básicamente hay dos tipos diferentes de cosas aquí:
- Sistemas de archivos normales, que guardan archivos en directorios con datos y metadatos, de la forma familiar (incluidos enlaces blandos, enlaces duros, etc.). Estos a menudo, pero no siempre, están respaldados por un dispositivo de bloque para almacenamiento persistente (un tmpfs vive solo en RAM, pero por lo demás es idéntico a un sistema de archivos normal). La semántica de estos es familiar; leer, escribir, renombrar, etc., todo funciona de la manera que espera.
- Sistemas de archivos virtuales, de varios tipos.
/proc
y/sys
son ejemplos aquí, al igual que 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 una semántica que, en cierto sentido, es 'personalizada'. Por lo tanto, cuando lee de un archivo bajo/proc
, en realidad no está accediendo a una pieza específica de datos que ha sido almacenada por otra cosa que la escribió anteriormente, como en un sistema de archivos normal. Básicamente, está haciendo una llamada al 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 extraño comportamiento de los archivos bajo/proc
, como por ejemplo pretender ser enlaces simbólicos cuando en realidad no lo son.
La clave es que /dev
es en realidad, por lo general, uno de los primeros. Es normal en las distribuciones modernas tener /dev
ser algo así como un tmpfs, pero en los sistemas más antiguos, era normal que fuera un directorio simple en el disco, sin ningún atributo especial. La clave es que los archivos bajo /dev
son nodos de dispositivos, un tipo de archivo especial similar a FIFO o sockets Unix; un nodo de dispositivo tiene un número mayor y menor, y leerlos o escribirlos es hacer una llamada a un controlador del kernel, al igual que leer o escribir un FIFO es llamar al kernel para almacenar en búfer su salida en una tubería. Este controlador puede hacer lo que quiera, pero generalmente toca el hardware de alguna manera, p. para acceder a un disco duro o reproducir sonido en los altavoces.
Para responder a las preguntas originales:
-
Hay dos cuestiones pertinentes a si el 'archivo existe' o no; estos son si el archivo de nodo del dispositivo existe literalmente y si el código del kernel 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 así para observar eventos de hardware y crear y destruir automáticamente los nodos del dispositivo bajo/dev
respectivamente. Pero los sistemas más antiguos, o las compilaciones personalizadas livianas, pueden tener todos sus nodos de dispositivos literalmente en el disco, creados con anticipación. Mientras tanto, cuando lee estos archivos, está haciendo una llamada al código del kernel que está determinado por los números de dispositivo principal y secundario; si estos no son razonables (por ejemplo, está tratando de leer un dispositivo de bloque que no existe), obtendrá algún tipo de error de E/S. -
La forma en que determina qué código del kernel llamar para qué archivo de dispositivo varía. Para sistemas de archivos virtuales como
/proc
, implementan su propioread
ywrite
funciones; el kernel simplemente 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 de dispositivos, se envía en función de los números de dispositivos principales y secundarios.
Aquí hay una lista de archivos de /dev/sda1
en mi servidor Arch Linux casi actualizado:
% ls -li /dev/sda1
1294 brw-rw---- 1 root disk 8, 1 Nov 9 13:26 /dev/sda1
Así que la entrada del directorio en /dev/
para sda
tiene un número de inodo, 1294. Es un archivo real en el disco.
Mire dónde suele aparecer el tamaño del archivo. En su lugar aparece "8, 1". 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 C (fragmento):
/*
* Structure of an inode on the disk
*/
struct ext2_inode {
__u16 i_mode; /* File mode */
Esa estructura nos muestra la estructura en disco del inodo de un archivo. Hay muchas cosas interesantes en esa estructura; Míralo detenidamente.
El i_mode
elemento de struct ext2_inode
tiene 16 bits, y usa solo 9 para el usuario/grupo/otro, permisos de lectura/escritura/ejecución, y otros 3 para setuid, setgid y sticky. Tiene 4 bits para diferenciar entre tipos como "archivo sin formato", "enlace", "directorio", "tubería con nombre", "zócalo de la familia Unix" y "dispositivo de bloque".
El kernel de Linux puede seguir el algoritmo habitual de búsqueda de directorios y luego tomar una decisión basada en los permisos y las banderas en el i_mode
elemento. Para 'b', archivos de dispositivo de bloque, puede encontrar los números de dispositivo principal y secundario y, tradicionalmente, usar el número de dispositivo principal para buscar un puntero a alguna función del kernel (un controlador de dispositivo) que se ocupa de los discos. El número de dispositivo menor generalmente se usa como, por ejemplo, el número de dispositivo de bus SCSI, o el número de dispositivo EIDE o algo así.
Algunas otras decisiones sobre cómo manejar un archivo como /proc/cpuinfo
se realizan en función del tipo de sistema de archivos. Si haces:
% mount | grep proc
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
puedes ver que /proc
tiene un tipo de sistema de archivos de "proc". Lectura de un archivo en /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 haría que el kernel usara diferentes funciones para localizar archivos y localizar datos de los archivos.
Al final del día todos son archivos para Unix, esa es la belleza de la abstracción.
La forma en que el kernel maneja los archivos, ahora eso 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/ventana para las variables y estructuras del kernel.
Recomiendo leer The Linux Kernel http://tldp.org/LDP/tlk/tlk.html y Linux Device Drivers, Third Edition 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 correspondiente a su pregunta.
http://www.tldp.org/LDP/tlk/dd/drivers.html