Quale comando devo usare per vedere il blocco iniziale e finale di un file nel file system?


10

Esiste un comando che produrrà i blocchi iniziale e finale di qualsiasi file?


1
quale tipo di file system: ext2,3,4; btrfs; XFS; zfs, ecc ...?
BeowulfNode42

@ BeowulfNode42: ext4, ntfs, fat32 sono quelli con cui mi occupo spesso ... quindi preferibilmente per questi tre ...
preciso il

La domanda dovrebbe essere migliorata (essere più precisi): la mia prima risposta sarebbe stata un programma che apre il file, legge il primo blocco, quindi cerca l'ultimo blocco e legge anche quello. Quindi cos'è "output" di un blocco? Il contenuto del blocco, l'indirizzo logico del blocco (all'interno del file, all'interno del file system, all'interno della partizione o all'interno del dispositivo del blocco) o l'indirizzo fisico del blocco (diventa interessante se il disco fa parte di alcuni RAID o LVM). Le risposte sembrano molto migliori della domanda.
U. Windl,

Risposte:


16

hdparm

Non sono sicuro al 100% che questo è quello che stai cercando, ma credo che tu possa farlo usando il comando hdparm, in particolare con il suo --fibmapinterruttore.

estratto

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

Esempio

Supponiamo di avere un file di esempio.

$ echo "this is a test file" > afile

Ora quando corriamo 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

Un altro bel metodo per scoprire i blocchi di inizio e fine di un file è filefrag. Tuttavia, per ottenere l'output desiderato dovrai utilizzare gli switch appropriati. Un aspetto positivo di questo strumento hdparmè che qualsiasi utente può eseguirlo, quindi non sudoè necessario. Dovrai utilizzare l' -b512interruttore in modo che le uscite vengano visualizzate in blocchi da 512 byte. Inoltre, dobbiamo dire filefragdi essere prolissi.

Esempio

$ 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 terzo metodo per ottenere gli LBA di un file è utilizzare debugfs. Questo metodo richiederà un po 'di matematica, ma ho pensato che fosse importante mostrare come si può convertire dal valore di estensione riportato dagli debugfsLBA, per quelli che potrebbero essere curiosi.

Quindi iniziamo con l'inode del file.

$ ls -i afile
6560281 afile

NOTA: potremmo anche usare il nome del file all'interno debugfsma per questa dimostrazione userò invece l'inode.

Ora otteniamo le statinformazioni tramite il debugfsnostro 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

Le informazioni importanti sono nella sezione estensioni. Questi sono in realtà blocchi di filesystem utilizzati da questo inode. Dobbiamo solo convertirli in LBA. Possiamo farlo attraverso la seguente equazione.

NOTA: Supponendo che il nostro filesystem utilizzi blocchi di dimensioni 4k e che l'hardware sottostante utilizzi unità da 512 byte, dobbiamo moltiplicare gli esiti per 8.

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

Esempio

Quindi nel nostro esempio la nostra estensione iniziale e finale è la stessa, dal momento che il nostro file rientra in un'unica estensione.

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

Quindi i nostri LBA sono 282439184..282439191.

Riferimenti


questi sono alcuni link ... grazie per la risposta e i link ...
preciso il

2
@hash - sono i resti di me che cercano di trovare altri 2 metodi per determinare gli LBA. 8-). Lo sto scrivendo come la mia Q sul sito ora.
slm

@hash - Ho aggiunto un'altra tecnica usando filefrag.
slm

@hash - Ho aggiunto un'altra tecnica usando debugfs.
slm

ho provato filefragcon blocchi di dimensioni disponibili di 1024 e 2048 .. debugfscon estensioni di file più grandi : 0 - 12187 .. mi prenderò il mio tempo e capirò .. è di grande aiuto, grazie ...
preciso il

4

Numero del settore relativo al dispositivo a blocchi che contiene l'FS (non l'intero disco)

(Si noti che hdparm --fibmapè relativo all'intero disco, non alla partizione o a qualsiasi altro blockdev che contiene FS. Richiede anche root.)

filefrag -efunziona bene e utilizza lo ioctl generico ed efficienteFIEMAP , quindi dovrebbe funzionare praticamente su qualsiasi filesystem (incluso il BTRFS spesso strano, anche per i file compressi BTRFS). Tornerà a FIBMAP per filesystem / kernel senza supporto 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-only

Se stai usando xfs, allora xfs_bmapha un output migliore: ti mostra dove ci sono buchi, mentre filefragha l'estensione successiva a partire da un settore successivo. Utilizza blocchi da 512B, non importa quale sia effettivamente la dimensione del filesystem. (in genere 4k su Linux). Ti mostra in quale gruppo di allocazione si trova ciascuna estensione e come è allineata sui confini della striscia 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

-lè ridondante quando -vviene utilizzato, ma per qualche motivo scrivo sempre -vpl. -plè un output più compatto.


Entrambi filefrage xfs_bmapti mostrano le estensioni preallocate.

$ 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 --fibmapè utile solo se si desidera un numero di settore relativo all'intero disco rigido , non all'interno della partizione in cui si trova il filesystem. Non funziona con il software RAID (o presumibilmente qualsiasi altra cosa tra il filesystem e un disco rigido). Richiede anche root. Nonostante il nome dell'opzione, in realtà utilizza FIEMAPquando disponibile (la più recente ioctl con estensione-map, non con il vecchio ioctl con blocco lento).

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

0

Quindi, per un dato file, vuoi sapere quali numeri di blocco del disco contengono l'inizio e la fine di quel file.

debugfs (8) sembra promettente per ext2 / 3/4 FS

stat (1), ls -i, lsof (8) forniscono il numero di inode, ma non molto altro sui blocchi del disco.

head / tail --bytes = 1024 è utile per il contenuto del file, ma non per i blocchi del disco.

dd (1) sarà ciò che si desidera ispezionare il contenuto del blocco: fare attenzione alla differenza tra i parametri seek = e skip = ed evitare = / dev / ... a meno che non si desideri davvero che il file di output sia un dispositivo .


no non è quello che intendevo ... sono i numeri di blocco del disco che mi interessano.
preciso il

0

hdparm --fibmapelencherà i blocchi occupati da un file. Nota che potrebbero non essere contigui, quindi "inizio e fine" non ha senso.


Penso che l'interruttore a cui ti riferisci sia --fibmap. Inoltre è necessario specificare un nome file con esso. Esempio: hdparm --fibmap afile.
slm

@slm, oops, yes, typo ... e ho pensato che fosse ovvio che devi nominare il file in questione.
psusi,

Non è stato per me fino a quando non ho provato a eseguirlo. Fino ad oggi la mia esperienza passata con hdparmera a livello di intera unità, non l'ho mai usata per i file prima.
slm
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.