130 votos

¿Es seguro analizar un archivo/proc /?

Quiero analizar /proc/net/tcp/ , pero ¿es seguro?

¿Cómo debo abrir y leer archivos de /proc/ y no tener miedo, que algún otro proceso (o el sistema operativo propio) estará cambiando lo al mismo tiempo?

94voto

Greg Price Puntos 1901

En general, no. (Así que la mayoría de las respuestas están equivocadas.) Se puede estar seguro, dependiendo de lo que la propiedad que usted desea. Pero es fácil terminar con errores en el código si se asume demasiado acerca de la consistencia de un archivo en /proc. Ver, por ejemplo, este error que vino desde suponiendo que /proc/mounts fue consistente instantánea.

Por ejemplo:

  • /proc/uptime está totalmente atómica, como alguien mencionó en otra respuesta -, pero sólo desde Linux 2.6.30, que es menos de dos años de edad. Así que incluso esta pequeña, trivial archivo estaba sujeta a una condición de carrera hasta entonces, y aún lo es en la mayoría de los enterprise núcleos. Ver fs/proc/uptime.c para la fuente actual, o la confirmación que hizo atómica. En un pre-kernel 2.6.30, puede open el archivo, read un poco de ella, entonces si, posteriormente, volver y read de nuevo, la pieza que se obtiene será incompatible con la primera pieza. (Me acaba de mostrar esta : trate usted mismo para la diversión.)

  • /proc/mounts es atómica dentro de un único read de llamada del sistema. Así que si usted read de todo el archivo a la vez, tiene un único coherente instantánea de los puntos de montaje en el sistema. Sin embargo, si utiliza varios read las llamadas al sistema, y si el archivo es grande, esto es exactamente lo que sucederá si el uso normal de e/S de las bibliotecas y no prestar atención especial a este tema, usted estará sujeto a una condición de carrera. No sólo usted no obtener una consistente instantánea, pero los puntos de montaje de los cuales estaban presentes antes de empezar y nunca dejó de estar presente podría van a faltar en lo que ves. Al ver que atómica para uno read(), mire m_start() en fs/namespace.c y el ver que agarrar un semáforo que los guardias de la lista de puntos de montaje, que se mantiene hasta m_stop(), que se llama cuando la read() está hecho. Para ver lo que puede salir mal, ver este fallo desde el año pasado (la misma que he enlazado más arriba) en lo contrario de software de alta calidad que alegremente leído /proc/mounts.

  • /proc/net/tcp, que es el que realmente estás preguntando acerca de, incluso es menos consistente que el que. Es atómica sólo dentro de cada fila de la tabla. Para ver esto, mire listening_get_next() en net/ipv4/tcp_ipv4.c y established_get_next() justo abajo en el mismo archivo, y ver las esclusas se llevará a cabo en cada entrada. No tengo repro código práctico para demostrar la falta de consistencia de una fila a fila, pero no hay bloqueos de allí (o cualquier otra cosa), que sería consistente. Lo cual tiene sentido si se piensa en ello -- la creación de redes es a menudo un super-ocupado parte del sistema, por lo que no vale la sobrecarga que presentar un coherente punto de vista en esta herramienta de diagnóstico.

La otra pieza que mantiene /proc/net/tcp atómica dentro de cada fila es el almacenamiento en búfer en seq_read(), que se puede leer en fs/seq_file.c. Esto asegura que una vez que read() parte de una fila, el texto de la fila entera se guarda en un buffer para que la próxima read() va a llegar el resto de la fila antes de iniciar uno nuevo. El mismo mecanismo es utilizado en /proc/mounts para mantener cada fila atómica incluso si usted no los múltiples read() llamadas, y es también el mecanismo que /proc/uptime en los núcleos nuevos usos para mantenerse atómica. Que el mecanismo ya no búfer de todo el archivo, debido a que el núcleo es cauteloso acerca del uso de la memoria.

La mayoría de los archivos en /proc será al menos tan consistente como /proc/net/tcp, con cada fila de una imagen coherente de una entrada en cualquier tipo de información que están proporcionando, porque la mayoría de ellos utilizan el mismo seq_file de abstracción. Como /proc/uptime ejemplo ilustra, sin embargo, algunos archivos fueron todavía se está migrando al uso seq_file recientemente, en 2009; apuesto a que todavía hay algunos que utilizan los antiguos mecanismos y no tienen ni siquiera ese nivel de atomicidad. Estas advertencias son raramente documentado. Para un archivo determinado, su única garantía es la de leer la fuente.

En el caso de /proc/net/tcp, se puede leer y analizar cada línea sin miedo. Pero si se intenta sacar conclusiones de varias líneas a la vez-cuidado, otros procesos y el núcleo están cambiando mientras usted la lea, y que son, probablemente, la creación de un bug.

39voto

Blagovest Buyukliev Puntos 22767

Aunque los archivos en /proc aparecen como archivos normales en el espacio de usuario, en realidad no son archivos sino entidades que apoyan las operaciones de archivo estándar de espacio de usuario (open, read, close). Tenga en cuenta que esto es muy diferente de tener un archivo ordinario en el disco que está siendo cambiado por el kernel.

Todos los kernel que hace es imprimir su estado interno en su propia memoria utilizando un sprintf-como de la función, y que la memoria se copia en el espacio de usuario cada vez que se emite una read(2) de llamada del sistema.

El kernel se encarga de estas llamadas de una manera totalmente diferente que para los archivos normales, lo que podría significar que la totalidad de la captura de los datos que usted leerá podría estar listo en el momento en que open(2) , mientras que el núcleo se asegura de que las llamadas concurrentes son consistentes y atómica. Yo no he leído en ningún lugar, pero en realidad no tiene sentido ser lo contrario.

Mi consejo es echar un vistazo a la implementación de un proc archivo en su particular sabor de Unix. Esto es realmente un problema de implementación (como es el formato y el contenido de la salida) que no se rige por una norma.

El ejemplo más sencillo sería la aplicación de la uptime de archivos / proc de Linux: http://lxr.free-electrons.com/source/fs/proc/uptime.c. Nota cómo todo el búfer se produce en la función de devolución de llamada suministrados single_open.

16voto

Bruce Puntos 4241

/proc es un sistema de archivos virtual : de hecho, solo le da un conveniente punto de vista de las interioridades del kernel. Es, definitivamente, seguro que leer (por eso es de aquí) pero es arriesgado en el largo plazo, como el interior de estos archivos virtuales pueden evolucionar con la versión más reciente del kernel.

EDITAR

Más información disponible en la documentación de proc de Linux kernel doc, capítulo 1.4 Redes Yo no puedo encontrar si la información de cómo la información evolucionan con el tiempo. Pensé que era congelado en abierto, pero no puede tener una respuesta definitiva.

EDIT2

Según Sco doc (no linux, pero estoy bastante seguro de que todos los sabores de *nix se comportan como tales)

Aunque el estado del proceso y en consecuencia, el contenido de /proc los archivos pueden cambiar de un instante a instante, en una sola lectura(2) de /proc el archivo está garantizado para volver un `cuerdo" representación del estado, que es decir, la lectura será un atómica instantánea del estado del proceso. No hay tal garantía se aplica a los sucesivas lecturas aplicado a un /proc archivo para la ejecución de un proceso. En además, la atomicidad es específicamente no se garantiza que para cualquier I/O aplicado a as (espacio de direcciones) archivo; la el contenido de cualquier proceso de dirección del el espacio puede estar simultáneamente modificado por un LWP de ese proceso, o cualquier otro el proceso en el sistema.

13voto

Job Puntos 8339

El procfs API en el kernel de Linux proporciona una interfaz para asegurarse de que lee volver consistente de datos. Leer los comentarios en __proc_file_read. Elemento 1) en el gran bloque de comentario explica esta interfaz.

Dicho esto, es evidente que hasta la aplicación de un determinado proc archivo para utilizar esta interfaz correctamente para asegurarse de que sus datos devueltos es consistente. Así que, para responder a tu pregunta: no, el kernel no garantiza la consistencia de los archivos proc durante una lectura, sino que proporciona los medios para la aplicación de los archivos para darle consistencia.

6voto

wallyk Puntos 33150

Tengo la fuente para Linux 2.6.27.8 práctico ya me estoy haciendo de controlador de desarrollo en el momento en que un embedded BRAZO de destino.

El archivo ...linux-2.6.27.8-lpc32xx/net/ipv4/raw.c en la línea 934 contiene, por ejemplo

    seq_printf(seq, "%4d: %08X:%04X %08X:%04X"
            " %02X %08X:%08X %02X:%08lX %08X %5d %8d %lu %d %p %d\n",
            i, src, srcp, dest, destp, sp->sk_state,
            atomic_read(&sp->sk_wmem_alloc),
            atomic_read(&sp->sk_rmem_alloc),
            0, 0L, 0, sock_i_uid(sp), 0, sock_i_ino(sp),
            atomic_read(&sp->sk_refcnt), sp, atomic_read(&sp->sk_drops));

que salidas

[wally@zenetfedora ~]$ cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode                                                     
   0: 017AA8C0:0035 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 15160 1 f552de00 299
   1: 00000000:C775 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 13237 1 f552ca00 299
...

en función raw_sock_seq_show() que es parte de una jerarquía de procfs las funciones de manejo. El texto no se genera hasta un read() solicitud de la /proc/net/tcp archivo, un mecanismo razonable desde procfs lee son seguramente mucho menos común que la actualización de la información.

Algunos conductores (como el mío) implementar el proc_read función con una sola sprintf(). La complicación adicional en el núcleo de los controladores de la aplicación es manejar potencialmente muy larga de salida que no puede caber en el intermedio, el núcleo de espacio de búfer durante una sola lectura.

He probado que con un programa usando un 64 kb de buffer de lectura, pero resulta en un núcleo de espacio de búfer de 3072 bytes en mi sistema para proc_read para devolver los datos. Varias llamadas con el avance de los punteros son necesarios para obtener algo más que mucho texto devuelto. Yo no sé cuál es la forma correcta de hacer los datos devueltos coherente cuando más de uno de e/s es necesario. Ciertamente, cada entrada en /proc/net/tcp es auto-consistente. Hay alguna probabilidad de que las líneas de lado a lado de instantáneas en diferentes momentos.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X