Quelle commande dois-je utiliser pour voir le bloc de début et de fin d'un fichier dans le système de fichiers?

10

Existe-t-il une commande qui affichera les blocs de début et de fin d'un fichier?

précis
la source
1
quel type de système de fichiers: ext2,3,4; btrfs; xfs; zfs, etc ...?
BeowulfNode42
@ BeowulfNode42: ext4, ntfs, fat32 sont ceux avec lesquels je traite souvent ... donc de préférence pour ces trois ...
précis
La question devrait être améliorée (soyez plus précis): Ma première réponse aurait été un programme qui ouvre le fichier, lit le premier bloc, puis cherche le dernier bloc et le lit aussi. Alors, quelle est la "sortie" d'un bloc? Le contenu du bloc, l'adresse logique du bloc (à l'intérieur du fichier, à l'intérieur du système de fichiers, à l'intérieur de la partition ou à l'intérieur du périphérique de bloc), ou l'adresse physique du bloc (devient intéressante si le disque fait partie d'un RAID ou LVM). Les réponses semblent bien meilleures que la question.
U. Windl

Réponses:

16

hdparm

Je ne suis pas sûr à 100% que c'est ce que vous recherchez, mais je pense que vous pouvez le faire en utilisant la commande hdparm, en particulier avec son --fibmapcommutateur.

extrait

   --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.

Exemple

Disons que nous avons un exemple de fichier.

$ echo "this is a test file" > afile

Maintenant, quand nous courons 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

Une autre méthode intéressante pour trouver les blocs de début et de fin d'un fichier est filefrag. Vous devrez cependant utiliser les commutateurs appropriés pour obtenir la sortie souhaitée. Un avantage de cet outil hdparmest que tout utilisateur peut l'exécuter, donc aucun sudon'est requis. Vous devrez utiliser le -b512commutateur pour que les sorties soient affichées dans des blocs de 512 octets. Nous devons également dire filefragd'être verbeux.

Exemple

$ 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

Une troisième méthode pour obtenir les LBA d'un fichier consiste à utiliser debugfs. Cette méthode nécessitera un peu de calcul, mais j'ai pensé qu'il était important de montrer comment on peut convertir des valeurs d'étendue rapportées par debugfsen LBA, pour ceux qui pourraient être curieux.

Commençons donc par l'inode du fichier.

$ ls -i afile
6560281 afile

REMARQUE: nous pourrions également utiliser le nom du fichier à l'intérieur, debugfsmais pour cette démonstration, je vais utiliser l'inode à la place.

Maintenant, obtenons les statinformations via debugfssur notre inode.

$ 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

Les informations importantes se trouvent dans la section étendue. Il s'agit en fait de blocs de système de fichiers utilisés par cet inode. Nous avons juste besoin de les convertir en LBA. Nous pouvons le faire grâce à l'équation suivante.

REMARQUE: En supposant que notre système de fichiers utilise des tailles de bloc de 4k et que le matériel sous-jacent utilise des unités de 512 octets, nous devons multiplier les exents par 8.

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

Exemple

Ainsi, dans notre exemple, notre étendue de début et de fin est la même, car notre fichier tient dans une seule étendue.

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

Nos LBA sont donc 282439184..282439191.

Références

slm
la source
ce sont quelques liens ... merci pour la réponse et les liens ...
précis
2
@hash - ils sont les restes de moi essayant de trouver 2 autres méthodes pour déterminer les LBA. 8-). Je l'écris comme mon propre Q sur le site maintenant.
slm
@hash - J'ai ajouté une autre technique en utilisant filefrag.
slm
@hash - J'ai ajouté une autre technique en utilisant debugfs.
slm
j'ai essayé filefragavec des tailles de blocs disponibles de 1024 et 2048 .. debugfsavec une extension de fichier plus grande : 0 - 12187 .. je vais prendre mon temps et comprendre .. c'est une grande aide, merci ...
précis
4

Numéro de secteur par rapport au périphérique de bloc contenant le FS (pas le disque entier)

(Notez que cela hdparm --fibmapest relatif à l'ensemble du disque, pas à la partition ou à tout autre blockdev contenant le FS. Il nécessite également root.)

filefrag -efonctionne bien et utilise l' ioctl générique et efficaceFIEMAP , il devrait donc fonctionner sur à peu près n'importe quel système de fichiers (y compris le BTRFS souvent étrange, même pour les fichiers compressés BTRFS). Il reviendra à FIBMAP pour les systèmes de fichiers / noyaux sans prise en charge 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

XFS uniquement

Si vous utilisez xfs, la xfs_bmapsortie est plus agréable: elle vous montre où il y a des trous, tandis filefragque la prochaine étendue commence à un secteur ultérieur. Il utilise des blocs de 512B, quelle que soit la taille de bloc du système de fichiers. (généralement 4k sous Linux). Il vous montre dans quel groupe d'allocation chaque extension se trouve et comment elle est alignée sur les limites de la bande 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

-lest redondant lorsqu'il -vest utilisé, mais pour une raison quelconque, je tape toujours -vpl. -plest une sortie plus compacte.


Les deux filefraget xfs_bmapvous montrent les extensions préallouées.

$ 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 --fibmapn'est utile que si vous voulez un numéro de secteur par rapport à l'ensemble du disque dur , pas dans la partition sur laquelle se trouve le système de fichiers. Il ne fonctionne pas en plus du RAID logiciel (ou probablement de tout autre élément entre le système de fichiers et un disque dur). Il nécessite également root. Malgré le nom de l'option, il utilise en fait FIEMAPlorsqu'il est disponible (le plus récent ioctl de carte d'extension, pas l'ancien ioctl de carte de bloc lent).

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

Donc, pour un fichier donné, vous voulez savoir quels numéros de bloc de disque contiennent le début et la fin de ce fichier.

debugfs (8) semble prometteur pour les FS ext2 / 3/4

stat (1), ls -i, lsof (8) fournissent le numéro d'inode, mais pas grand-chose d'autre sur les blocs de disques.

head / tail --bytes = 1024 est utile pour le contenu des fichiers, mais pas pour les blocs de disques.

dd (1) sera ce que vous voulez inspecter le contenu du bloc - soyez attentif à la différence entre les paramètres de recherche = et de saut = et évitez de = / dev / ... sauf si vous voulez vraiment que le fichier de sortie soit un périphérique .

D McKeon
la source
non ce n'est pas ce que je voulais dire ... c'est le numéro de bloc du disque qui m'intéresse.
précis
0

hdparm --fibmaprépertorie les blocs qu'un fichier occupe. Notez qu'ils peuvent ne pas être contigus, donc "début et fin" n'a pas de sens.

psusi
la source
Je pense que le commutateur dont vous parlez est --fibmap. Vous devez également spécifier un nom de fichier avec. Exemple: hdparm --fibmap afile.
slm
@slm, oups, oui, faute de frappe ... et j'ai pensé qu'il était évident que vous deviez nommer le fichier en question.
psusi
Ce n'était pas pour moi jusqu'à ce que j'essaie de l'exécuter. Jusqu'à aujourd'hui, mon expérience passée avec hdparmétait sur un niveau de disque entier, je ne l'ai jamais utilisé pour des fichiers auparavant.
slm