Jakiego polecenia używam, aby zobaczyć blok początkowy i końcowy pliku w systemie plików?

10

Czy jest jakieś polecenie, które wyświetli blok początkowy i końcowy dowolnego pliku?

precyzyjny
źródło
1
jaki typ systemu plików: ext2,3,4; btrfs; xfs; ZFS itp.?
BeowulfNode42
@ BeowulfNode42: ext4, NTFS, FAT32 to te, z którymi często mam do czynienia ... więc najlepiej dla tych trzech ...
dokładnie
Pytanie powinno zostać poprawione (a dokładniej): Moją pierwszą odpowiedzią byłby jakiś program, który otwiera plik, czyta pierwszy blok, a następnie szuka ostatniego bloku i też go przeczyta. Czym jest „wyjście” bloku? Zawartość bloku, adres logiczny bloku (w pliku, w systemie plików, w partycji lub w urządzeniu blokowym) lub adres fizyczny bloku (staje się interesujący, jeśli dysk jest częścią RAID lub LVM). Odpowiedzi wydają się znacznie lepsze niż pytanie.
U. Windl

Odpowiedzi:

16

hdparm

Nie jestem w 100% pewien, że tego właśnie szukasz, ale uważam, że możesz to zrobić za pomocą polecenia hdparm, a konkretnie jego --fibmapprzełącznika.

fragment

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

Przykład

Powiedzmy, że mamy przykładowy plik.

$ echo "this is a test file" > afile

Teraz kiedy biegniemy 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

Inną przyjemną metodą znajdowania początkowych i końcowych bloków pliku jest filefrag. Musisz jednak użyć odpowiednich przełączników, aby uzyskać pożądaną moc wyjściową. Zaletą tego narzędzia hdparmjest to, że każdy użytkownik może go uruchomić, więc nie sudojest to wymagane. Musisz użyć -b512przełącznika, aby wyjścia były wyświetlane w 512-bajtowych blokach. Musimy też powiedzieć, filefragżeby być gadatliwym.

Przykład

$ 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

Trzecią metodą uzyskania LBA pliku jest skorzystanie z niego debugfs. Ta metoda wymaga trochę matematyki, ale pomyślałem, że ważne jest, aby pokazać, w jaki sposób można przekonwertować wartości zakresu zgłaszane przez debugfsLBA dla tych, którzy mogą być ciekawi.

Zacznijmy od i-węzła pliku.

$ ls -i afile
6560281 afile

UWAGA: Możemy również użyć nazwy pliku wewnątrz, debugfsale do tej demonstracji użyję zamiast tego i-węzła.

Teraz uzyskamy statinformacje za pośrednictwem debugfsnaszego i-węzła.

$ 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

Ważna informacja znajduje się w części dotyczącej zakresu. W rzeczywistości są to bloki systemu plików używane przez ten i-węzeł. Musimy tylko przekonwertować je na LBA. Możemy to zrobić za pomocą następującego równania.

UWAGA: Zakładając, że nasz system plików używa bloków o wielkości 4k, a sprzęt bazowy używa 512 bajtów, musimy pomnożyć wartości wyjściowe przez 8.

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

Przykład

Zatem w naszym przykładzie nasz początkowy i końcowy zasięg jest taki sam, ponieważ nasz plik mieści się w jednym zakresie.

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

Nasze LBA to 282439184..282439191.

Bibliografia

slm
źródło
to niektóre linki ... dzięki za odpowiedź i linki ...
dokładnie
2
@ Hash - są to pozostałości mojej próby znalezienia 2 innych metod określania LBA. 8-). Piszę to teraz jako własne Q na stronie.
slm
@ Hash - Dodałem inną technikę filefrag.
slm
@ Hash - Dodałem inną technikę debugfs.
slm
próbowałem filefragz dostępnymi rozmiarami bloków 1024 i 2048 .. debugfsz większymi rozmiarami plików : 0 - 12187 .. Nie spieszę się i zrozumiem ... to świetna pomoc, dzięki ...
dokładnie
4

Numer sektora w stosunku do urządzenia blokowego zawierającego FS (nie całego dysku)

(Pamiętaj, że hdparm --fibmapdotyczy całego dysku, nie partycji ani innego bloku blokującego FS. Wymaga również rootowania.)

filefrag -edziała dobrze i używa ogólnego i wydajnego FIEMAPioctl , więc powinien działać na prawie każdym systemie plików (w tym często dziwnym BTRFS, nawet dla plików skompresowanych BTRFS). Wróci do FIBMAP dla systemów plików / jąder bez obsługi 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

Tylko XFS

Jeśli używasz xfs, to xfs_bmapma ładniejszy wynik: pokazuje, gdzie są dziury, a filefragpo prostu ma następny zasięg, zaczynając od późniejszego sektora. Wykorzystuje bloki 512B, a nie taki, jaki faktycznie jest rozmiar bloku systemu plików. (zazwyczaj 4k w systemie Linux). Pokazuje, w której grupie alokacji jest każdy zakres i jak jest wyrównany na granicach pasków 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

-ljest zbędny, gdy -vjest używany, ale z jakiegoś powodu zawsze piszę -vpl. -pljest bardziej kompaktowy.


Zarówno filefragi xfs_bmappokazują wstępnie przydzielone zakresy.

$ 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 --fibmapjest przydatny tylko wtedy, gdy chcesz mieć numer sektora w stosunku do całego dysku twardego , a nie w obrębie partycji, na której znajduje się system plików. Nie działa na oprogramowaniu RAID (lub prawdopodobnie na czymkolwiek innym między systemem plików a dyskiem twardym). Wymaga również rootowania. Pomimo nazwy opcji, faktycznie używa, FIEMAPgdy jest dostępna (nowszy ioctl z mapą zasięgu, a nie stary powolny ioctl z mapą bloków).

# hdparm --fibmap ..../xpsp3.vdi
Unable to determine start offset LBA for device, aborting.
Peter Cordes
źródło
0

Tak więc dla danego pliku chcesz wiedzieć, które numery bloków dysku zawierają początek i koniec tego pliku.

debugfs (8) wygląda obiecująco na FS2 ext2 / 3/4

stat (1), ls -i, lsof (8) podają numer i-węzła, ale niewiele więcej o blokach dysków.

head / tail --bytes = 1024 jest przydatny dla zawartości pliku, ale nie bloków dysku.

dd (1) będzie tym, co chcesz sprawdzić zawartość bloku - zwróć uwagę na różnicę między parametrami seek = i skip = i unikaj = / dev / ..., chyba że naprawdę chcesz, aby plik wyjściowy był urządzeniem .

D McKeon
źródło
nie, nie to miałem na myśli ... to numery bloków dysku, którymi się interesuję.
dokładnie
0

hdparm --fibmapwyświetli listę bloków zajmowanych przez plik. Pamiętaj, że mogą nie być ciągłe, więc „początek i koniec” nie ma sensu.

psusi
źródło
Myślę, że zmiana, o której mówisz, jest --fibmap. Musisz także podać nazwę pliku w / it. Przykład: hdparm --fibmap afile.
slm
@slm, ups, tak, literówka ... i pomyślałem, że to oczywiste, że musisz nazwać dany plik.
psusi
To nie było dla mnie, dopóki nie spróbowałem go uruchomić. Do dzisiaj moje wcześniejsze doświadczenia z hdparmcałym poziomem napędu nigdy nie były używane w przypadku plików.
slm