¿Qué comando utilizo para ver el bloque inicial y final de un archivo en el sistema de archivos?

10

¿Hay algún comando que muestre los bloques inicial y final de cualquier archivo?

preciso
fuente
1
qué tipo de sistema de archivos: ext2,3,4; btrfs; xfs; zfs, etc ...?
BeowulfNode42
@ BeowulfNode42: ext4, ntfs, fat32 son los que trato con frecuencia ... así que preferiblemente para estos tres ...
preciso
La pregunta debería mejorarse (sea más preciso): mi primera respuesta habría sido algún programa que abre el archivo, lee el primer bloque, luego busca el último bloque y lo lee también. Entonces, ¿cuál es la "salida" de un bloque? El contenido del bloque, la dirección lógica del bloque (dentro del archivo, dentro del sistema de archivos, dentro de la partición o dentro del dispositivo de bloque), o la dirección física del bloque (se vuelve interesante si el disco forma parte de algún RAID o LVM). Las respuestas parecen mucho mejores que la pregunta.
U. Windl

Respuestas:

16

hdparm

No estoy 100% seguro de que esto sea lo que está buscando, pero creo que puede hacerlo usando el comando hdparm, específicamente con su --fibmapinterruptor.

extracto

   --fibmap
          When  used,  this  must  be the only option given.  It requires a 
          file path as a parameter, and will print out a list of the block 
          extents (sector ranges) occupied by that file on disk.  Sector 
          numbers are  given as absolute LBA numbers, referenced from sector 
          0 of the physical device rather than from the partition or 
          filesystem.  This information can then be used for a variety of 
          purposes,  such  as examining the degree of fragmenation of larger 
          files, or determining appropriate sectors to deliberately corrupt 
          during fault-injection testing procedures.

          This option uses the new FIEMAP (file extent map) ioctl() when 
          available,  and  falls  back  to  the older  FIBMAP (file block 
          map) ioctl() otherwise.  Note that FIBMAP suffers from a 32-bit 
          block-number interface, and thus not work beyond 8TB or 16TB.  
          FIBMAP is also very slow, and  does  not  deal well  with  
          preallocated uncommitted extents in ext4/xfs filesystems, unless a 
          sync() is done before using this option.

Ejemplo

Digamos que tenemos un archivo de muestra.

$ echo "this is a test file" > afile

Ahora cuando corremos hdparm.

$ sudo hdparm --fibmap afile 

afile:
 filesystem blocksize 4096, begins at LBA 0; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0  282439184  282439191          8

filefrag

Otro buen método para descubrir los bloques iniciales y finales de un archivo es filefrag. Sin embargo, deberá usar los interruptores adecuados para obtener la salida deseada. Una ventaja de esta herramienta hdparmes que cualquier usuario puede ejecutarla, por lo que no sudose requiere. Deberá usar el -b512interruptor para que las salidas se muestren en bloques de 512 bytes. También necesitamos decir filefragque sea detallado.

Ejemplo

$ filefrag -b512 -v afile
Filesystem type is: ef53
File size of afile is 20 (8 block of 512 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..       7:  282439184.. 282439191:      8:             eof
afile: 1 extent found

debugfs

Un tercer método para obtener los LBA de un archivo es hacer uso de debugfs. Este método requerirá un poco de matemática, pero pensé que era importante mostrar cómo se puede convertir del valor extents reportado debugfsa LBA, para aquellos que puedan ser curiosos.

Entonces, comencemos con el inodo del archivo.

$ ls -i afile
6560281 afile

NOTA: También podríamos usar el nombre del archivo dentro, debugfspero para esta demostración voy a usar el inodo en su lugar.

Ahora obtengamos la statinformación debugfssobre nuestro inodo.

$ sudo debugfs -R "stat <6560281>" /dev/mapper/fedora_greeneggs-home
debugfs 1.42.7 (21-Jan-2013)
Inode: 6560281   Type: regular    Mode:  0664   Flags: 0x80000
Generation: 1999478298    Version: 0x00000000:00000001
User:  1000   Group:  1000   Size: 20
File ACL: 0    Directory ACL: 0
Links: 1   Blockcount: 8
Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x52be10c3:a640e994 -- Fri Dec 27 18:44:03 2013
 atime: 0x52bff8a1:a9f08020 -- Sun Dec 29 05:25:37 2013
 mtime: 0x52be0fe7:18a2f344 -- Fri Dec 27 18:40:23 2013
crtime: 0x52be0dd8:64394b00 -- Fri Dec 27 18:31:36 2013
Size of extra inode fields: 28
Extended attributes stored in inode body: 
  selinux = "unconfined_u:object_r:user_home_t:s0\000" (37)
EXTENTS:
(0):35304898

La información importante está en la sección de extensiones. Estos son en realidad bloques del sistema de archivos que están siendo utilizados por este inodo. Solo necesitamos convertirlos a LBA. Podemos hacer esto a través de la siguiente ecuación.

NOTA: Suponiendo que nuestro sistema de archivos usa tamaños de bloque de 4k y que el hardware subyacente usa unidades de 512 bytes, debemos multiplicar los exents por 8.

beginning LBA = (BEGIN EXTENT) * 8
ending LBA    = (((ENDING EXTENT) + 1) * 8) - 1

Ejemplo

Entonces, en nuestro ejemplo, nuestra extensión inicial y final es la misma, ya que nuestro archivo se ajusta dentro de una sola extensión.

beginning LBA = 35304898 * 8             = 282439184
ending LBA    = ((35304898 + 1) * 8) - 1 = 282439191

Entonces nuestros LBA son 282439184..282439191.

Referencias

slm
fuente
estos son algunos enlaces ... gracias por la respuesta y los enlaces ...
preciso
2
@hash: son los restos de mí tratando de encontrar otros 2 métodos para determinar los LBA. 8-). Lo estoy escribiendo como mi propia Q en el sitio ahora.
slm
@hash: agregué otra técnica usando filefrag.
slm
@hash: agregué otra técnica usando debugfs.
slm
Lo intenté filefragcon los tamaños de bloques disponibles de 1024 y 2048 ... debugfscon extensiones de archivo más grandes : 0 - 12187 ... Me tomaré mi tiempo y entenderé ... eso es una gran ayuda, gracias ...
preciso
4

Número de sector relativo al dispositivo de bloque que contiene el FS (no todo el disco)

(Tenga en cuenta que hdparm --fibmapes relativo a todo el disco, no a la partición o cualquier otro blockdev que contenga el FS. También requiere root).

filefrag -efunciona bien, y utiliza el genérico y eficiente FIEMAPioctl , por lo que debería funcionar en casi cualquier sistema de archivos (incluyendo los BTRFS menudo extraños, incluso para los archivos comprimidos-BTRFS). Recurrirá a FIBMAP para sistemas de archivos / núcleos sin soporte FIEMAP.

$ filefrag xpsp3.vdi          # some old sparse disk image I had lying around
xpsp3.vdi: 110 extents found
$ filefrag -e xpsp3.vdi
Filesystem type is: 58465342
File size of xpsp3.vdi is 5368730112 (1310726 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..       5: 1322629241..1322629246:      6:            
   1:       13..      13: 1322620799..1322620799:      1: 1322629247:
   2:       15..      47: 1323459271..1323459303:     33: 1322620800:
...
 160:   899498..  915839: 1325792977..1325809318:  16342: 1325725438:
 161:  1307294.. 1307391: 1323938199..1323938296:     98: 1325809319: last
xpsp3.vdi: 110 extents found

Solo XFS

Si está utilizando xfs, entonces xfs_bmaptiene una salida más agradable: le muestra dónde hay agujeros, mientras que filefragla próxima extensión comienza en un sector posterior. Utiliza bloques de 512B, no lo que sea realmente el tamaño de bloque del sistema de archivos. (normalmente 4k en Linux). Le muestra en qué grupo de asignación se encuentra cada extensión y cómo se alinea en los límites de banda RAID.

$ xfs_bmap -vvpl xpsp3.vdi   # the extra -v prints a key to the flags
xpsp3.vdi:
 EXT: FILE-OFFSET           BLOCK-RANGE              AG AG-OFFSET              TOTAL FLAGS
   0: [0..47]:              10581033928..10581033975 13 (83912..83959)            48 01111
   1: [48..103]:            hole                                                  56
   2: [104..111]:           10580966392..10580966399 13 (16376..16383)             8 01010
   3: [112..119]:           hole                                                   8
 ...
 322: [10458352..10459135]: 10591505592..10591506375 13 (10555576..10556359)     784 01111
 323: [10459136..10485807]: hole                                               26672
FLAG Values:   # this part is only here with -vv
    010000 Unwritten preallocated extent
    001000 Doesn't begin on stripe unit
    000100 Doesn't end   on stripe unit
    000010 Doesn't begin on stripe width
    000001 Doesn't end   on stripe width

-les redundante cuando -vse usa, pero por alguna razón siempre escribo -vpl. -plEs una salida más compacta.


Ambos filefragy xfs_bmapte muestran extensiones preasignadas.

$ fallocate --length $((1024*1024*8)) prealloced_file
$ filefrag -e prealloced_file
Filesystem type is: 58465342
File size of prealloced_file is 8388608 (2048 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..    2047: 1325371648..1325373695:   2048:             last,unwritten,eof
prealloced_file: 1 extent found
$ xfs_bmap -vvpl prealloced_file 
prealloced_file:
 EXT: FILE-OFFSET      BLOCK-RANGE              AG AG-OFFSET            TOTAL FLAGS
   0: [0..16383]:      10602973184..10602989567 13 (22023168..22039551) 16384 10010
 FLAG Values:
    010000 Unwritten preallocated extent
    001000 Doesn't begin on stripe unit
    000100 Doesn't end   on stripe unit
    000010 Doesn't begin on stripe width
    000001 Doesn't end   on stripe width
$ dd if=/dev/zero of=prealloced_file conv=notrunc bs=4k count=10 seek=10000
40960 bytes (41 kB) copied, 0.000335111 s, 122 MB/s
$ xfs_bmap -vpl prealloced_file                                           
prealloced_file:
 EXT: FILE-OFFSET      BLOCK-RANGE              AG AG-OFFSET            TOTAL FLAGS
   0: [0..16383]:      10602973184..10602989567 13 (22023168..22039551) 16384 10010
   1: [16384..79999]:  hole                                             63616
   2: [80000..80895]:  10603013120..10603014015 13 (22063104..22063999)   896 00111
 # oops, wrote past EOF and extended the file, instead of in the middle of the preallocated extent
$ dd if=/dev/zero of=prealloced_file conv=notrunc bs=4k count=10 seek=100
40960 bytes (41 kB) copied, 0.000212986 s, 192 MB/s
$ xfs_bmap -vpl prealloced_file 
prealloced_file:
 EXT: FILE-OFFSET      BLOCK-RANGE              AG AG-OFFSET            TOTAL FLAGS
   0: [0..16383]:      10602973184..10602989567 13 (22023168..22039551) 16384 10010
   1: [16384..79999]:  hole                                             63616
   2: [80000..80895]:  10603013120..10603014015 13 (22063104..22063999)   896 00111
# If you check *right away*, XFS's delayed allocation hasn't happened yet.
# FIEMAP on xfs only reflects allocations, which lag behind completed writes.  fsync first if you need it, IIRC.
$ xfs_bmap -vpl prealloced_file 
prealloced_file:
 EXT: FILE-OFFSET      BLOCK-RANGE              AG AG-OFFSET            TOTAL FLAGS
   0: [0..799]:        10602973184..10602973983 13 (22023168..22023967)   800 10111
   1: [800..879]:      10602973984..10602974063 13 (22023968..22024047)    80 01111
   2: [880..16383]:    10602974064..10602989567 13 (22024048..22039551) 15504 11010
   3: [16384..79999]:  hole                                             63616
   4: [80000..80895]:  10603013120..10603014015 13 (22063104..22063999)   896 00111
$ filefrag -e prealloced_file 
Filesystem type is: 58465342
File size of prealloced_file is 41000960 (10010 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..      99: 1325371648..1325371747:    100:             unwritten
   1:      100..     109: 1325371748..1325371757:     10:            
   2:      110..    2047: 1325371758..1325373695:   1938:             unwritten
   3:    10000..   10111: 1325376640..1325376751:    112: 1325373696: last,eof
prealloced_file: 2 extents found

hdparm --fibmapsolo es útil si desea un número de sector relativo a todo el disco duro , no dentro de la partición en la que se encuentra el sistema de archivos. No funciona sobre RAID de software (o presumiblemente cualquier otra cosa entre el sistema de archivos y un disco duro). También requiere root. A pesar del nombre de la opción, en realidad se usa FIEMAPcuando está disponible (el ioctl de mapa de extensión más nuevo, no el viejo ioctl de mapa de bloques lento).

# hdparm --fibmap ..../xpsp3.vdi
Unable to determine start offset LBA for device, aborting.
Peter Cordes
fuente
0

Entonces, para un archivo dado, desea saber qué números de bloque de disco contienen el inicio y el final de ese archivo.

debugfs (8) parece prometedor para ext2 / 3/4 FSes

stat (1), ls -i, lsof (8) proporcionan el número de inodo, pero no mucho más sobre los bloques de disco.

head / tail --bytes = 1024 es útil para el contenido del archivo, pero no para los bloques de disco.

dd (1) será lo que desea inspeccionar el contenido del bloque: esté atento a la diferencia entre los parámetros seek = y skip =, y evite = = dev / ... a menos que realmente desee que el archivo de salida sea un dispositivo .

D McKeon
fuente
no, eso no es lo que quise decir ... son los números de bloque del disco lo que me preocupa.
preciso
0

hdparm --fibmapenumerará los bloques que ocupa un archivo. Tenga en cuenta que pueden no ser contiguos, por lo que "inicio y fin" no tiene sentido.

psusi
fuente
Creo que el cambio al que te refieres es --fibmap. También debe especificar un nombre de archivo w / it. Ejemplo: hdparm --fibmap afile.
slm
@slm, oops, sí, error tipográfico ... y pensé que era obvio que debes nombrar el archivo en cuestión.
psusi
No fue para mí hasta que intenté ejecutarlo. Hasta el día de hoy, mi experiencia pasada hdparmfue en un nivel de unidad completo, nunca lo usé para archivos antes.
slm