Perintah apa yang saya gunakan untuk melihat blok awal dan akhir file dalam sistem file?

10

Apakah ada perintah yang akan menampilkan blok awal dan akhir dari file apa pun?

tepat
sumber
1
jenis sistem file apa: ext2,3,4; btrfs; xfs; zfs, dll ...?
BeowulfNode42
@ BeowulfNode42: ext4, ntfs, fat32 adalah yang sering saya tangani ... jadi sebaiknya untuk ketiga ini ...
tepatnya
Pertanyaannya harus ditingkatkan (lebih tepatnya): Jawaban pertama saya adalah beberapa program yang membuka file, membaca blok pertama, kemudian mencari ke blok terakhir dan membacanya juga. Jadi apa itu "output" dari sebuah blok? Konten blok, alamat logis blok (di dalam file, di dalam sistem file, di dalam partisi, atau di dalam perangkat blok), atau alamat fisik blok (menjadi menarik jika disk adalah bagian dari beberapa RAID atau LVM). Jawabannya tampak jauh lebih baik daripada pertanyaan.
U. Windl

Jawaban:

16

hdparm

Saya tidak 100% yakin ini yang Anda cari, tetapi saya yakin Anda bisa melakukan ini menggunakan perintah hdparm, khususnya dengan --fibmapsaklarnya.

kutipan

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

Contoh

Katakanlah kita memiliki file sampel.

$ echo "this is a test file" > afile

Sekarang saat kita berlari 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

Metode lain yang bagus untuk mengetahui blok awal & akhir file adalah filefrag. Anda harus menggunakan sakelar yang sesuai, untuk mendapatkan hasil yang diinginkan. Salah satu kelebihan alat ini hdparmadalah bahwa setiap pengguna dapat menjalankannya, jadi tidak sudodiperlukan. Anda harus menggunakan -b512sakelar sehingga output ditampilkan dalam blok 512 byte. Kita juga perlu mengatakan filefraguntuk menjadi verbose.

Contoh

$ 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

Metode ketiga untuk mendapatkan LBA file adalah dengan memanfaatkan debugfs. Metode ini akan membutuhkan sedikit matematika, tetapi saya pikir penting untuk menunjukkan bagaimana seseorang dapat mengkonversi dari nilai luasan yang dilaporkan oleh debugfsLBA, bagi mereka yang mungkin ingin tahu.

Jadi mari kita mulai dengan inode file.

$ ls -i afile
6560281 afile

CATATAN: Kita juga bisa menggunakan nama file di dalam debugfstetapi untuk demonstrasi ini saya akan menggunakan inode sebagai gantinya.

Sekarang mari kita dapatkan statinformasi debugfstentang inode kami.

$ 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

Informasi penting ada di bagian luasan. Ini sebenarnya adalah blok filesystem yang digunakan oleh inode ini. Kami hanya perlu mengubahnya menjadi LBA. Kita dapat melakukan ini melalui persamaan berikut.

CATATAN: Dengan asumsi bahwa filesystem kami menggunakan ukuran blok 4k dan perangkat keras yang mendasarinya menggunakan unit 512 byte, kita perlu mengalikan exents dengan 8.

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

Contoh

Jadi, dalam contoh kita, tingkat awal dan akhir kita sama, karena file kita cocok dalam satu tingkat.

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

Jadi LBA kami adalah 282439184..282439191.

Referensi

slm
sumber
ini adalah beberapa tautan ... terima kasih atas jawaban dan tautannya ...
tepatnya
2
@ hash - mereka adalah sisa dari saya yang mencoba menemukan 2 metode lain untuk menentukan LBA. 8-). Saya menuliskannya sebagai Q saya sendiri di situs sekarang.
slm
@ hash - Saya telah menambahkan teknik lain menggunakan filefrag.
slm
@ hash - Saya telah menambahkan teknik lain menggunakan debugfs.
slm
saya mencoba filefragdengan bloksi tersedia 1024 dan 2048 .. debugfsdengan luas file yang lebih besar : 0 - 12187 .. saya akan mengambil waktu saya dan mengerti .. itu sangat membantu, terima kasih ...
tepatnya
4

Nomor sektor relatif terhadap perangkat blok yang menahan FS (bukan seluruh disk)

(Catatan yang hdparm --fibmaprelatif terhadap seluruh disk, bukan partisi atau apa pun blockdev lainnya memegang FS. Ini juga membutuhkan root.)

filefrag -eberfungsi dengan baik, dan menggunakan ioctl yang generik dan efisienFIEMAP , sehingga harus bekerja pada hampir semua sistem file (termasuk BTRFS yang sering-aneh, bahkan untuk file yang dikompresi BTRFS). Ini akan kembali ke FIBMAP untuk sistem file / kernel tanpa dukungan 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

Khusus XFS

Jika Anda menggunakan xfs, maka xfs_bmapmemiliki output yang lebih bagus: Ini menunjukkan Anda di mana ada lubang, sementara filefraghanya memiliki tingkat selanjutnya mulai dari sektor selanjutnya. Ia menggunakan blok-blok 512B, bukan apa pun ukuran sebenarnya dari filesystem. (biasanya 4k di Linux). Ini menunjukkan kepada Anda di mana grup alokasi setiap tingkat berada, dan bagaimana ia diluruskan pada batas-batas garis 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

-lredundan saat -vdigunakan, tetapi untuk beberapa alasan saya selalu mengetik -vpl. -ploutput lebih kompak.


Keduanya filefragdan xfs_bmapmenunjukkan kepada Anda luasan yang telah dialokasikan sebelumnya.

$ 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 --fibmaphanya berguna jika Anda ingin nomor sektor relatif ke seluruh hard drive , bukan di dalam partisi filesystem aktif. Itu tidak bekerja di atas RAID perangkat lunak (atau mungkin hal lain antara sistem file dan hard drive). Itu juga membutuhkan root. Terlepas dari nama opsi, ia sebenarnya menggunakan FIEMAPbila tersedia (ioctl-map tingkat yang lebih baru, bukan ioctl blok-peta lama).

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

Jadi, untuk file yang diberikan, Anda ingin tahu nomor blok disk mana yang berisi awal dan akhir file itu.

debugfs (8) terlihat menjanjikan untuk ext2 / 3/4 FSes

stat (1), ls -i, lsof (8) memberikan nomor inode, tetapi tidak banyak lagi tentang blok disk.

head / tail --bytes = 1024 berguna untuk konten file, tetapi tidak untuk blok disk.

dd (1) akan menjadi apa yang Anda inginkan untuk memeriksa konten blok - waspadai perbedaan antara parameter seek = dan skip =, dan hindari = / dev / ... kecuali Anda benar - benar ingin file output menjadi perangkat .

D McKeon
sumber
tidak bukan itu yang saya maksud ... ini nomor blok disk yang saya khawatirkan.
tepatnya
0

hdparm --fibmapakan mencantumkan blok yang ditempati file. Perhatikan bahwa mereka mungkin tidak bersebelahan, jadi "mulai dan berakhir" tidak masuk akal.

psusi
sumber
Saya pikir saklar yang Anda maksudkan adalah --fibmap. Anda juga perlu menentukan nama file dengan itu. Contoh: hdparm --fibmap afile.
slm
@slm, oops, ya, salah ketik ... dan saya pikir sudah jelas Anda harus memberi nama file yang dimaksud.
psusi
Itu tidak bagi saya sampai saya mencoba menjalankannya. Sampai hari ini pengalaman saya yang lalu dengan hdparmberada di tingkat drive keseluruhan, tidak pernah menggunakannya untuk file sebelumnya.
slm