Tôi sử dụng lệnh nào để xem khối bắt đầu và kết thúc của một tệp trong hệ thống tệp?


10

Có lệnh nào sẽ xuất các khối đầu và cuối của bất kỳ tệp nào không?


1
loại hệ thống tập tin: ext2,3,4; btrfs; xfs; zfs, v.v ...?
BeowulfNode42

@ BeowulfNode42: ext4, ntfs, fat32 là những người tôi thường xử lý ... tốt nhất là cho ba người này ...
chính xác là

Câu hỏi nên được cải thiện (chính xác hơn): Câu trả lời đầu tiên của tôi sẽ là một chương trình mở tệp, đọc khối đầu tiên, sau đó tìm đến khối cuối cùng và cũng đọc nó. Vậy "đầu ra" của một khối là gì? Nội dung của khối, địa chỉ lôgic của khối (bên trong tệp, bên trong hệ thống tệp, bên trong phân vùng hoặc bên trong thiết bị khối) hoặc địa chỉ vật lý của khối (trở nên thú vị nếu đĩa là một phần của RAID hoặc LVM). Các câu trả lời có vẻ tốt hơn nhiều so với câu hỏi.
U. Windl

Câu trả lời:


16

hdparm

Tôi không chắc chắn 100% đây là những gì bạn đang tìm kiếm nhưng tôi tin rằng bạn có thể làm điều này bằng cách sử dụng lệnh hdparm, đặc biệt là với công --fibmaptắc của nó .

đoạn trích

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

Thí dụ

Nói rằng chúng tôi có một tập tin mẫu.

$ echo "this is a test file" > afile

Bây giờ khi chúng tôi chạy 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

Một phương pháp hay khác để tìm ra các khối bắt đầu và kết thúc của tệp là filefrag. Bạn sẽ cần phải sử dụng các công tắc thích hợp mặc dù, để có được đầu ra mong muốn. Một ưu điểm của công cụ hdparmnày là bất kỳ người dùng nào cũng có thể chạy nó, do đó không sudobắt buộc. Bạn sẽ cần sử dụng công -b512tắc để các đầu ra được hiển thị trong các khối 512 byte. Ngoài ra chúng ta cần phải nói filefragdài dòng.

Thí dụ

$ 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

gỡ lỗi

Phương pháp thứ ba để có được các LBA của tệp là sử dụng debugfs. Phương pháp này sẽ đòi hỏi một chút toán học, nhưng tôi nghĩ điều quan trọng là chỉ ra cách người ta có thể chuyển đổi từ giá trị phạm vi được báo cáo debugfscho các LBA, cho những người có thể tò mò.

Vì vậy, hãy bắt đầu với inode của tập tin.

$ ls -i afile
6560281 afile

LƯU Ý: Chúng tôi cũng có thể sử dụng tên của tệp trong debugfsnhưng để trình diễn này, tôi sẽ sử dụng inode thay thế.

Bây giờ hãy lấy statthông tin qua debugfsvề inode của chúng tôi.

$ 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

Các thông tin quan trọng là trong phần phạm vi. Đây thực sự là các khối hệ thống tập tin đang được sử dụng bởi inode này. Chúng ta chỉ cần chuyển đổi chúng sang LBA. Chúng ta có thể làm điều này thông qua các phương trình sau đây.

LƯU Ý: Giả sử hệ thống tệp của chúng tôi sử dụng kích thước khối 4k và phần cứng bên dưới sử dụng đơn vị 512 byte, chúng tôi cần nhân 8 lần xuất hiện.

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

Thí dụ

Vì vậy, trong ví dụ của chúng tôi, mức độ bắt đầu và kết thúc của chúng tôi là như nhau, vì tệp của chúng tôi phù hợp trong một phạm vi duy nhất.

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

Vậy các LBA của chúng tôi là 282439184..282439191.

Người giới thiệu


đây một số liên kết ... cảm ơn câu trả lời và liên kết ...
chính xác là

2
@hash - Chúng là tàn dư của tôi khi cố gắng tìm 2 phương pháp khác để xác định LBA. số 8-). Bây giờ tôi đang viết nó dưới dạng Q của riêng tôi trên trang web.
slm

@hash - Tôi đã thêm một kỹ thuật khác bằng cách sử dụng filefrag.
slm

@hash - Tôi đã thêm một kỹ thuật khác bằng cách sử dụng debugfs.
slm

tôi đã thử filefragvới các kích thước có sẵn là 1024 và 2048 .. debugfsvới phạm vi tệp lớn hơn : 0 - 12187 .. tôi sẽ dành thời gian và hiểu .. đó là một sự trợ giúp tuyệt vời, cảm ơn ...
chính xác là

4

Số ngành liên quan đến thiết bị khối giữ FS (không phải toàn bộ đĩa)

(Lưu ý rằng hdparm --fibmapcó liên quan đến toàn bộ đĩa, không phải phân vùng hoặc bất kỳ blockdev nào khác giữ FS. Nó cũng yêu cầu root.)

filefrag -ehoạt động tốt và sử dụng ioctl chung và hiệu quảFIEMAP , do đó, nó sẽ hoạt động trên hầu hết mọi hệ thống tệp (bao gồm cả BTRFS thường kỳ lạ, ngay cả đối với các tệp được nén BTRFS). Nó sẽ quay trở lại FIBMAP cho các hệ thống tập tin / hạt nhân mà không có hỗ trợ 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

Chỉ XFS

Nếu bạn đang sử dụng xfs, thì xfs_bmapcó đầu ra đẹp hơn: Nó cho bạn thấy nơi có lỗ, trong khi filefragchỉ có phạm vi tiếp theo bắt đầu từ một khu vực sau. Nó sử dụng các khối 512B, không phải bất cứ thứ gì mà hệ thống tập tin thực sự có kích thước. (thường là 4k trên Linux). Nó cho bạn biết nhóm phân bổ nào trong từng phạm vi và cách nó được căn chỉnh trên ranh giới dải 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

-llà dư thừa khi -vđược sử dụng, nhưng vì một số lý do tôi luôn gõ -vpl. -pllà đầu ra nhỏ gọn hơn.


Cả hai filefragxfs_bmapcho bạn thấy phạm vi preallocated.

$ 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 --fibmapchỉ hữu ích nếu bạn muốn số ngành liên quan đến toàn bộ ổ cứng , không nằm trong phân vùng mà hệ thống tập tin được bật. Nó không hoạt động trên RAID phần mềm (hoặc có lẽ là bất cứ thứ gì khác giữa hệ thống tập tin và ổ cứng). Nó cũng yêu cầu root. Mặc dù tên của tùy chọn, nó thực sự sử dụng FIEMAPkhi có sẵn (ioctl bản đồ phạm vi mới hơn, không phải là ioctl bản đồ khối chậm cũ).

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

0

Vì vậy, đối với một tệp đã cho, bạn muốn biết số khối đĩa nào chứa phần đầu và phần cuối của tệp đó.

debugfs (8) có vẻ hứa hẹn cho ext2 / 3/4 FSes

stat (1), ls -i, lsof (8) cung cấp số inode, nhưng không nhiều về khối đĩa.

head / tail --bytes = 1024 rất hữu ích cho nội dung tệp, nhưng không phải là khối đĩa.

dd (1) sẽ là những gì bạn muốn kiểm tra nội dung khối - hãy cảnh giác với sự khác biệt giữa các tham số tìm kiếm = và bỏ qua = và tránh = / dev / ... trừ khi bạn thực sự muốn tệp đầu ra là một thiết bị .


không, đó không phải là ý tôi ... đó là số khối của đĩa tôi quan tâm.
chính xác

0

hdparm --fibmapsẽ liệt kê các khối mà một tập tin chiếm giữ. Lưu ý rằng chúng có thể không liền kề nhau, vì vậy "bắt đầu và kết thúc" không có ý nghĩa.


Tôi nghĩ rằng công tắc bạn đang đề cập đến là --fibmap. Ngoài ra, bạn cần chỉ định một tên tệp w / it. Ví dụ : hdparm --fibmap afile.
slm

@slm, oops, vâng, lỗi đánh máy ... và tôi nghĩ rõ ràng là bạn phải đặt tên cho tập tin đó.
psusi

Nó đã không cho tôi cho đến khi tôi cố gắng để chạy nó. Cho đến hôm nay, trải nghiệm trước đây của tôi hdparmlà ở cấp độ toàn bộ ổ đĩa, chưa bao giờ sử dụng nó cho các tệp trước đây.
slm
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.