Si hago (en una cáscara de Bourne-like):
exec 3> file 4>&3 5> file 6>> file
Los descriptores de archivo 3 y 4, dado que 4 se dup()
editó a partir de 3, comparten la misma descripción de archivo abierto (mismas propiedades, mismo desplazamiento dentro del archivo ...). Mientras que los descriptores de archivo 5 y 6 de ese proceso están en una descripción de archivo abierta diferente (por ejemplo, cada uno tiene su propio puntero en el archivo).
Ahora, en la lsof
salida, todo lo que vemos es:
zsh 21519 stephane 3w REG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 4w REG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 5w REG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 6w REG 254,2 0 10505865 /home/stephane/file
Es un poco mejor con lsof +fg
:
zsh 21519 stephane 3w REG W,LG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 4w REG W,LG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 5w REG W,LG 254,2 0 10505865 /home/stephane/file
zsh 21519 stephane 6w REG W,AP,LG 254,2 0 10505865 /home/stephane/file
(aquí en Linux 3.16) en el que vemos que fd 6 tiene diferentes indicadores, por lo que debe ser una descripción de archivo abierto diferente de la de fd 3, 4 o 5, pero a partir de eso no podemos decir que fd 5 está en un Descripción de archivo abierto diferente . Con -o
, también podríamos ver el desplazamiento, pero de nuevo el mismo desplazamiento no garantiza que sea la misma descripción de archivo abierto .
¿Hay alguna forma no intrusiva de descubrirlo? Externamente, o para un proceso de propios descriptores de archivos?
1 . Un enfoque heurístico podría ser cambiar las marcas de un fcntl()
archivo con y ver qué otros descriptores de archivos tienen sus banderas actualizadas como resultado, pero eso obviamente no es ideal ni a prueba de tontos
fuente
Respuestas:
Para Linux 3.5 y versiones posteriores, esto se puede lograr con kcmp (3) :
La página del manual proporciona un ejemplo específico para el caso de uso que solicitó OP. Tenga en cuenta que esta llamada al sistema requiere que el núcleo se compile con
CONFIG_CHECKPOINT_RESTORE
set.fuente
struct file *
punteros.Lo que está buscando para comparar son los
struct file
punteros a los que apuntan los descriptores de archivo. (Dentro del núcleo hay unatask_struct
estructura de datos para cada subproceso. Contiene un puntero a otra estructura llamadafiles_struct
. Y esa estructura contiene una matriz de punteros, cada uno astruct file
. Es elstruct file
que contiene el desplazamiento de búsqueda, las banderas abiertas y un algunos otros campos)No conozco ninguna forma visible para el usuario de ver los punteros
files_struct
que no sean el uso de algunas herramientas intrusivas. Por ejemplo, SystemTap podría recibir un PID y podría encontrar el correspondientetask_struct
y seguir los punteros. Sin embargo, si buscas pasivo, creo que eso es todo. Dell lanzó una herramienta hace mucho tiempo llamada KME (Kernel Memory Editor) que brindaba una interfaz similar a una hoja de cálculo para vivir la memoria del kernel y podía hacer lo que deseaba, pero nunca se transfirió a 64 bits. (Lo intenté y nunca lo hice funcionar por completo, y no estaba seguro de por qué).Una razón usted no está encontrando
lsof
para ser útil es que no ve los punteros o bien (pero mira la+f
opción para los sistemas no Linux). Teóricamente, podría comparar todos los campos en elstruct file
y pensar que las dos estructuras son iguales, pero aún podrían ser deopen(2)
llamadas separadas .Eche un vistazo al script SystemTap de pfiles para obtener ideas. Si lo modificó para imprimir la dirección del
struct file
, tendría su solución. También puede verificar abrir_archivo_por_pid.stp ya que hay una función que recorre elfiles_struct
, es decir. la tabla de descriptores de archivos, mirando losstruct file
objetos ...¿Puedo preguntarte qué estás tratando de lograr?
fuente
probe begin
bloque y haga que use lafor_each_process
macro en un bloque de código C incrustado en el script (necesitará usar SystemTap en modo "guru" para incrustar código C). De hecho, para hacer esto interesante (!), Podría usar una de las matrices asociativas de SystemTap; use lafiles_struct
dirección como clave y una lista de PID / TID como valores. Ahora tiene una lista de todos los archivos abiertos y qué tareas los comparten (se pueden compartir entre padres / hijos). Responda nuevamente si desea hablar sobre SystemTap.Aquí es una solución específica Linux: / proc / self / fd es un directorio de enlaces simbólicos para los manejadores de archivos abiertos en el proceso actual. Simplemente puede comparar los valores del enlace. Se vuelve más complicado cuando se utiliza un proceso hijo, porque el niño tendrá un / proc / self diferente porque es un enlace simbólico depende pid. Puede solucionar este problema utilizando / proc / $$ / fd donde $$ es el pid deseado.
fuente