/ proc / PID / fd / X número de enlace

36

En Linux, en /proc/PID/fd/X, los enlaces para los descriptores de archivos que son tuberías o sockets tienen un número, como:

l-wx------ 1 user user 64 Mar 24 00:05 1 -> pipe:[6839]
l-wx------ 1 user user 64 Mar 24 00:05 2 -> pipe:[6839]
lrwx------ 1 user user 64 Mar 24 00:05 3 -> socket:[3142925]
lrwx------ 1 user user 64 Mar 24 00:05 4 -> socket:[3142926]
lr-x------ 1 user user 64 Mar 24 00:05 5 -> pipe:[3142927]
l-wx------ 1 user user 64 Mar 24 00:05 6 -> pipe:[3142927]
lrwx------ 1 user user 64 Mar 24 00:05 7 -> socket:[3142930]
lrwx------ 1 user user 64 Mar 24 00:05 8 -> socket:[3142932]
lr-x------ 1 user user 64 Mar 24 00:05 9 -> pipe:[9837788]

Como en la primera línea: 6839. ¿Qué representa ese número?

Thanatos
fuente

Respuestas:

36

Ese es el número de inodo para la tubería o el enchufe en cuestión.

Una tubería es un canal unidireccional, con un final de escritura y un final de lectura. En su ejemplo, parece que FD 5 y FD 6 están hablando entre sí, ya que los números de inodo son los mismos. (Tal vez no, sin embargo. Ver más abajo).

Más común que ver un programa que se habla a sí mismo a través de una tubería es un par de programas separados que se comunican entre sí, generalmente porque configura una tubería entre ellos con un shell:

shell-1$ ls -lR / | less

Luego, en otra ventana de terminal:

shell-2$ ...find the ls and less PIDs with ps; say 4242 and 4243 for this example...
shell-2$ ls -l /proc/4242/fd | grep pipe
l-wx------ 1 user user 64 Mar 24 12:18 1 -> pipe:[222536390]
shell-2$ ls -l /proc/4243/fd | grep pipe
l-wx------ 1 user user 64 Mar 24 12:18 0 -> pipe:[222536390]

Esto dice que la salida estándar del PID 4242 (FD 1, por convención) está conectada a una tubería con el número de inodo 222536390, y que la entrada estándar del PID 4243 (FD 0) está conectada a la misma tubería.

Todo lo cual es un largo camino para decir que lsla salida se está enviando a lessla entrada.

Volviendo a su ejemplo, FD 1 y FD 2 casi seguramente no se hablan entre sí. Lo más probable es que esto sea el resultado de vincular stdout (FD 1) y stderr (FD 2), por lo que ambos van al mismo destino. Puede hacerlo con un shell Bourne como este:

$ some-program 2>&1 | some-other-program

Entonces, si hurgaba /proc/$PID_OF_SOME_OTHER_PROGRAM/fd, encontraría un tercer FD conectado a una tubería con el mismo número de inodo que el adjunto a los FD 1 y 2 para la some-programinstancia. Esto también puede ser lo que está sucediendo con los FD 5 y 6 en su ejemplo, pero no tengo una teoría clara de cómo estos dos FD se unieron. Tendrías que saber qué está haciendo internamente el programa para resolverlo.

Warren Young
fuente
1
Creo que el ejemplo fue pidgin: tenía muchas tuberías y enchufes y otras cosas, así que fue un buen ejemplo. Una última pregunta: los inodes son específicos solo en el contexto de un sistema de archivos en particular, ¿correcto? Como en, podría tener el inodo 3 en mi /sistema de archivos, y otro (diferente) inodo 3 en mi /bootsistema de archivos.
Thanatos
44
Sí. En el caso del /procsistema de archivos, números de inodo se acaba de hacer sobre la marcha (véase get_next_ino()en fs/inode.cel núcleo), a partir de 0 cuando el sistema está recién arrancado. El mecanismo que los compone es compartido por varios de los sistemas de archivos impersistentes de Linux (proc, configfs, ramfs, autofs ...) entre los cuales los números de inodo son únicos aunque la semántica POSIX no lo exija. Sin embargo, ese es un caso bastante especial. La regla de la que está hablando generalmente se hace referencia en relación con los sistemas de archivos persistentes normales como ext3.
Warren Young
33

Para enchufes puede encontrar más información sobre el inodo en /proc/net/tcp, /proc/net/udpo /proc/net/unix. Por ejemplo:

ls -l /proc/<pid>/fd
lrwx------ 1 root root 64 May 26 22:03 3 -> socket:[53710569]

Vemos que el inodo es 53710569.

head -n1 < tcp ; grep -a 53710569 tcp
sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                   
155: 0100007F:001B 00000000:0000 0A 00000000:00000000 00:00000000 00000000  0        0 53710569 1 ffff88011f52c200 300 0 0 2 -1

En este caso, este es un socket de escucha (sin dirección remota), que escucha en el puerto local 27 (0x1B). Las direcciones IP tienen 4 bytes en hexadecimal en "notación de red", puede usar la inet_ntoafunción para convertirla a notación abcd estándar (127.0.0.1 en este caso).

Tenga en cuenta que estos archivos parecen tener 0 bytes pero tienen contenido si los lee. También tenga en cuenta que -ase requiere con grep ya que pueden (por ejemplo, con unix) parecer ser binarios.

Marki555
fuente
También hay /proc/net/tcp6y /proc/net/udp6para IPv6.
Craig McQueen