Información detallada sobre archivos dispersos en Linux

11

Tengo un archivo disperso, en el que solo se asignan algunos bloques:

~% du -h --apparent-size example
100K    example
~% du -h example
52K     example

Me gustaría saber qué bloques del archivo están realmente asignados. ¿Hay una llamada al sistema o una interfaz de kernel que podría usarse para obtener una lista de las asignaciones o los agujeros de archivo?

Simplemente verificar una cadena de ceros lo suficientemente larga (el enfoque utilizado por GNU cp, rsync, etc.) no funciona correctamente:

~% cp example example1  
~% du -h example1 
32K     example1

Detectó otras secuencias de ceros que en realidad se asignaron.

Juliano
fuente

Respuestas:

7

Hay una pregunta similar sobre SO . La respuesta actualmente aceptada por @ephemient sugiere usar una ioctlllamada fiemapque está documentada en linux/Documentation/filesystems/fiemap.txt. Citando de ese archivo:

El fiemap ioctl es un método eficiente para que el espacio de usuario obtenga asignaciones de extensión de archivo. En lugar de la asignación de bloque por bloque (como bmap), fiemap devuelve una lista de extensiones.

Parece que este es el tipo de información que estás buscando. El soporte de filesystems es nuevamente opcional:

Los sistemas de archivos que deseen admitir fiemap deben implementar una ->fiemap devolución de llamada en su inode_operationsestructura.

El apoyo a la SEEK_DATAy SEEK_HOLEargumentos para lseekque mencionas de Solaris se añadió en Linux 3.1 de acuerdo a la página del manual , por lo que podría utilizar eso también. Los fiemap ioctlparece ser mayor, por lo que podría ser más portable a través de diferentes versiones de Linux por ahora, mientras que lseekpodría ser más portable a través de los sistemas operativos Solaris, si tiene el mismo.

MvG
fuente
2
Usted puede obtener esta información mediante el uso de la FIEMAP --fibmapde la hdparmutilidad. Ver el manual.
Totor
2

Hay una colección de programas de Python llamados sparseutils que usan SEEK_HOLEy SEEK_DATApara determinar qué secciones del archivo se representan como agujeros y cuáles son datos. El uso es bastante sencillo. mksparsese puede usar para generar un archivo disperso de acuerdo con un diseño dado.

 $ echo hole,data,hole | mksparse --hole-size 4096 --data-size 4096 example
 $ du -sh example
 4.0K   example

El sparsemapprograma se puede usar para imprimir el diseño en stdout:

 $ sparsemap example
 HOLE 4096
 DATA 4096
 HOLE 4096
Ricardo
fuente
1

Depende del sistema de archivos. No creo que sea una llamada, por lo que muchas herramientas no manejan bien la copia de archivos dispersos. La cadena de herramientas GNU utiliza la búsqueda de grandes bloques de ceros, ya que les permite eliminar los bloques asignados no utilizados. Muchas herramientas de copia convertirán un archivo disperso en un archivo con todos los bloques asignados.

Probablemente tendrá que abrir el inodo y analizar el resultado. El formato de Inode depende del sistema de archivos. Algunos sistemas de archivos pueden tener parte de sus datos en el inodo mismo.

BillThor
fuente
1
Tiene que haber alguna forma independiente de FS para tener esta información. Leer directamente desde el inodo definitivamente no es una opción. Estaba buscando algo así SEEK_DATAcomo SEEK_HOLEparámetros para lseek(), como los que hay en Solaris: opensolarisforum.org/man/man2/lseek.html
Juliano
@Juliano Un vistazo a la opción lseek de Linux no tiene estas opciones. Solaris admite muy pocos sistemas de archivos, por lo que sería relativamente fácil de admitir. Linux admite una amplia variedad de sistemas de archivos, algunos de los cuales no admiten archivos dispersos. El soporte para SEEK_DATA / SEEK_HOLE impondría soporte en el código para todos los sistemas de archivos. Es posible que estos métodos no hagan lo que espera. Consulte blogs.sun.com/bonwick/entry/seek_hole_and_seek_data para obtener más información del lado del Sol.
BillThor
1
Los sistemas de archivos no necesitan soportar nada con la interfaz lseek (), el kernel incluye los módulos del sistema de archivos que admiten SEEK_DATA / SEEK_HOLE a través de una propiedad de módulo. Esto se encuentra en la página de manual y en el blog vinculado: "Para los sistemas de archivos que no proporcionan información sobre agujeros, el archivo se representará como una región de datos completa".
Juliano
@Juliano aún requiere modificaciones del kernel, así como cambios en lseek. Según la entrada del blog, esta es una funcionalidad bastante nueva en Sun. Para que funcione, el código del sistema de archivos también debe modificarse. Ciertamente requeriría cambios en todos los sistemas de archivos que admitan archivos dispersos para proporcionar los ganchos del núcleo.
BillThor