md raid5: dịch md số khu vực nội bộ sang offset


8

Tóm tắt về TL; DR : Dịch số md sector thành offset (s) trong /dev/mdXthiết bị và cách điều tra với xfs_db. Số ngành là từ sh->sectortrong linux/drivers/md/raid5.c:handle_parity_checks5().

Tôi không biết nội bộ MD, vì vậy tôi không biết chính xác phải làm gì với đầu ra từ printknhật ký tôi đã thêm.

Việc bù vào các thiết bị thành phần (cho ddhoặc trình soạn thảo / trình xem hex) cũng sẽ rất thú vị.

Tôi cho rằng tôi nên hỏi điều này trong danh sách gửi thư đột kích của Linux. Nó chỉ dành cho người đăng ký, hoặc tôi có thể đăng mà không đăng ký?


Tôi có xfs trực tiếp trên MD RAID5 của 4 đĩa trong máy tính để bàn của tôi (không có LVM). Một chà gần đây đã phát hiện ra một con số không mismatch_cnt(thực tế là 8, vì md hoạt động trên các trang 4kiB cùng một lúc).

Đây là RAID5, không phải RAID1 / RAID10 trong đó mismatch_cnt! = 0 có thể xảy ra trong quá trình hoạt động bình thường . (Các liên kết khác ở cuối trang wiki này có thể hữu ích với một số người.)

Tôi chỉ có thể mù quáng repair, nhưng sau đó tôi không biết nên kiểm tra tập tin nào để tham nhũng, ngoài việc mất bất kỳ cơ hội nào để chọn cách tái tạo. Câu trả lời của Frostschutz cho một câu hỏi tương tự là gợi ý duy nhất tôi tìm thấy để theo dõi lại sự khác biệt trong hệ thống tập tin. Nó cồng kềnh và chậm chạp, và tôi muốn sử dụng cái gì đó tốt hơn để thu hẹp nó xuống một vài tệp trước tiên.


Bản vá hạt nhân để thêm đăng nhập

Kỳ lạ thay, tính năng kiểm tra của md không báo cáo nơi tìm thấy lỗi . Tôi đã thêm một printktrong md / raid5.c để đăng nhập sh->sectorvào ifchi nhánh mà increments mddev->resync_mismatchestronghandle_parity_checks5() (vá nhỏ được công bố trên github , ban đầu dựa trên 4.5 rc4 từ kernel.org.) Đối với điều này là ok để sử dụng chung, nó có lẽ sẽ cần phải tránh làm ngập các bản ghi trong sửa chữa với rất nhiều sự không phù hợp (có thể chỉ đăng nhập nếu giá trị mới resync_mismatcheslà <1000?). Cũng có thể chỉ đăng nhập checkvà không repair.

Tôi khá chắc chắn rằng tôi đang ghi nhật ký một cái gì đó hữu ích (mặc dù tôi không biết nội bộ MD!), Bởi vì cùng một chức năng in số ngành đó trong trường hợp xử lý lỗi củaswitch .

Tôi đã biên dịch kernel đã sửa đổi của mình và khởi động nó, sau đó chạy lại kiểm tra:

[  399.957203] md: data-check of RAID array md125
...
[  399.957215] md: using 128k window, over a total of 2441757696k.
...
[21369.258985] md/raid:md125: check found mismatch at sector 4294708224    <-- custom log message
[25667.351869] md: md125: data-check done.

Bây giờ tôi không biết chính xác phải làm gì với số ngành đó. Là sh->sector * 512một địa chỉ tuyến tính bên trong /dev/md/t-r5(aka /dev/md125)? Đây có phải là số ngành trong mỗi thiết bị thành phần (vì vậy nó đề cập đến ba dữ liệu và một khu vực tương đương)? Tôi đoán điều sau, vì sự không tương đương trong RAID5 có nghĩa là các thành phần N-1 của thiết bị md đang ở trong tình trạng nguy hiểm, được bù trừ cho nhau bằng đơn vị sọc. Là ngành 0 là khởi đầu của thiết bị thành phần, hay nó là khu vực sau siêu khối hay gì đó? Có nhiều thông tin hơn trong handle_parity_checks5()đó tôi nên đã tính toán / đăng nhập không?

Nếu tôi chỉ muốn có được các khối không khớp, điều này có đúng không?

dd if=/dev/sda6 of=mmblock.0 bs=512 count=8 skip=4294708224
dd if=/dev/sdb6 of=mmblock.1 bs=512 count=8 skip=4294708224
dd if=/dev/sda6 of=mmblock.2 bs=512 count=8 skip=4294708224
dd if=/dev/sdd  of=mmblock.3 bs=512 count=8 skip=4294708224  ## not a typo: my 4th component is a smaller full-disk

# i.e.
sec_block() { for dev in {a,b,c}6 d; do dd if=/dev/sd"$dev" of="sec$1.$dev"  skip="$1"  bs=512 count=8;done; }; sec_block 123456

Tôi đoán là không, bởi vì tôi nhận được 4k số không từ cả bốn thành phần đột kích, và 0^0 == 0, vì vậy đó phải là sự tương đương chính xác, phải không?

Một nơi khác tôi đã thấy đề cập đến việc sử dụng địa chỉ sector trong md là cho sync_minsync_max(trong sysfs). Neil Brown trong danh sách đột kích linux , để trả lời câu hỏi về một ổ đĩa bị lỗi với số ngành từ đó hdrecover, trong đó Neil đã sử dụng số khu vực toàn đĩa làm số khu vực MD. Điều đó không đúng phải không? Các số ngành md sẽ không liên quan đến các thiết bị thành phần (phân vùng trong trường hợp đó), không phải là thiết bị đầy đủ mà phân vùng là một phần của?


khu vực tuyến tính đến tên tệp XFS:

Trước khi nhận ra rằng số md sector có lẽ là dành cho các thành phần, không phải thiết bị RAID, tôi đã thử sử dụng nó ở chế độ chỉ đọc xfs_db:

Gợi ý rất ngắn gọn của Dave Chinner về cách tìm XFS đang sử dụng một khối nhất định dường như không hoạt động với tôi. (Tôi đã mong đợi một số loại kết quả, đối với một số lĩnh vực, vì số lượng không nên vượt quá cuối thiết bị ngay cả khi đó không phải là khu vực không khớp)

# xfs_db -r /dev/md/t-r5 
xfs_db> convert daddr 4294708224 fsblock
0x29ad5e00 (699227648)
xfs_db> blockget -nv -b 699227648
xfs_db> blockuse -n       # with or without -c 8
must run blockget first

Huh? Tôi làm gì sai ở đây? Tôi đoán đây là một câu hỏi riêng biệt. Tôi sẽ thay thế nó bằng một liên kết nếu / khi tôi hỏi nó hoặc tìm câu trả lời cho phần này ở một nơi khác.

RAID5 của tôi về cơ bản là không hoạt động, không có hoạt động ghi và đọc tối thiểu (và noatime, do đó, đọc không tạo ra ghi).


Thêm công cụ về thiết lập của tôi, không có gì quan trọng ở đây

Nhiều tệp của tôi là video hoặc dữ liệu nén khác cung cấp một cách hiệu quả để biết liệu dữ liệu đó có chính xác hay không (có thể là tổng kiểm tra nội bộ ở định dạng tệp hoặc chỉ là liệu nó có giải mã được không có lỗi hay không). Điều đó sẽ làm cho phương thức loopback chỉ đọc này khả thi, một khi tôi biết nên kiểm tra tệp nào. Tuy nhiên, tôi không muốn chạy khác biệt 4 chiều của mọi tệp trong hệ thống tệp để tìm sự không phù hợp trước, khi hạt nhân có thông tin cần thiết trong khi kiểm tra và có thể dễ dàng đăng nhập nó.


của tôi /proc/mdstatcho mảng dữ liệu số lượng lớn của tôi:

md125 : active raid5 sdd[3] sda6[0] sdb6[1] sdc6[4]
      7325273088 blocks super 1.2 level 5, 512k chunk, algorithm 2 [4/4] [UUUU]
      bitmap: 0/19 pages [0KB], 65536KB chunk

Đó là trên các phân vùng trên ba ổ đĩa Toshiba 3TB và ổ đĩa xanh (chậm) WD25EZRS không phân vùng mà tôi sẽ thay thế bằng một chiếc Toshiba khác. (Sử dụng mdadm --replaceđể thực hiện trực tuyến mà không có lỗ hổng dự phòng. Tôi nhận ra sau một bản sao rằng tôi nên kiểm tra sức khỏe RAID trước cũng như sau đó, để phát hiện sự cố. , vì tôi đã gặp một số sự cố gần một năm trước, nhưng tôi không có nhật ký cũ và mdadm dường như không gửi thư về việc này theo mặc định (Ubuntu 15.10).

Các hệ thống tập tin khác của tôi nằm trên các thiết bị RAID10f2 được tạo từ các phân vùng trước đó trên ba HD lớn hơn (và RAID0 cho / var / tmp). RAID5 chỉ dành cho lưu trữ số lượng lớn, không /homehoặc /.

Các ổ đĩa của tôi đều ổn: Số lỗi SMART là 0 tất cả các bộ đếm khối xấu trên tất cả các ổ đĩa và các bài kiểm tra SMART ngắn + dài đã qua.


gần như trùng lặp của câu hỏi này không có câu trả lời:


Nếu số trong printk của bạn là một sector liên quan đến mảng, thì bạn cần chia nó cho chiều rộng sọc và có thể thêm phần bù bắt đầu để chuyển nó thành số sector liên quan đến thiết bị thành phần. iirc, nếu bạn đang sử dụng định dạng siêu dữ liệu mdadm không phải lúc nào cũng bắt đầu dữ liệu ở offset 0, thì phần bù nơi nó bắt đầu được liệt kê trong đầu ra của mdadm -E /dev/xxx.
psusi

Cũng lưu ý rằng ngay cả khi bạn tìm thấy vị trí của dữ liệu và có thể xác minh sự không phù hợp và có cách kiểm tra tính toàn vẹn của tệp bị hỏng (nếu dữ liệu thậm chí không thuộc về tệp; nó có thể chỉ miễn phí không gian hoặc siêu dữ liệu fs), sau đó hoàn toàn có thể và thậm chí có thể xảy ra rằng tính chẵn lẻ cũng sai và do đó, không có câu trả lời nào bạn có thể nhận được từ việc che giấu từng ổ dữ liệu lần lượt sẽ đúng.
psusi

@psusi: cảm ơn, vâng tôi biết nó có thể không phải là một phần của tập tin. Thật khó để diễn đạt điều đó mà không làm cho câu của tôi thực sự vụng về. Điểm thú vị là có lẽ không có sự tái tạo nào là đúng, vâng điều đó là có thể. Dù bằng cách nào, tôi sẽ hạnh phúc hơn rất nhiều khi biết nên đổi tên tập tin nào .damagedhoặc một cái gì đó, thay vì chỉ biết có thể có một tập tin bị hỏng ở đâu đó.
Peter Cordes

Câu trả lời:


2

TL; DR sh-> sector là số lượng cung trong các đĩa vật lý sau khi bắt đầu phần dữ liệu


Thiết lập

Đây là một thiết lập thử nghiệm đơn giản để minh họa:

  • / dev / raidme / rd [0-3], thiết bị 2GB
  • / dev / md127 được tạo dưới dạng raid5 trên 5, được khởi tạo dưới dạng xfs và chứa đầy dữ liệu ngẫu nhiên

Bây giờ để bắt đầu, hãy lấy một khối khác không và ghi đè lên nó

# dd if=/dev/raidme/rd0 bs=1k count=1 skip=10240 | hexdump -C | head
...
# dd if=/dev/zero of=/dev/raidme/rd0 bs=1k count=1 seek=10240
...
# dd if=/dev/raidme/rd2 bs=1k count=1 skip=10240 | hexdump  -C | head
1024 bytes (1.0 kB, 1.0 KiB) copied, 8.6021e-05 s, 11.9 MB/s
00000000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000400

Đảm bảo bộ đệm dm / md được xóa bằng cách dừng / gắn lại mảng và kiểm tra:

# mdadm --stop /dev/md127
# mdadm --assemble /dev/md127 /dev/raidme/rd*
# echo check > /sys/class/block/md127/md/sync_action
# dmesg | tail
...
[ 1188.057900] md/raid:md127: check found mismatch at sector 16384

Chặn trên đĩa

Được rồi, vì vậy trước tiên hãy kiểm tra 16384 phù hợp với những gì chúng tôi đã viết. Cuộc tấn công của tôi có một sọc 512k vì vậy tôi chắc chắn tôi đã viết một cái gì đó phù hợp với tiêu chí dễ phù hợp, chúng tôi đã viết ở 1024*10240ví dụ 0xa00000.

Bản vá của bạn cung cấp thông tin 16384, một điều cần lưu ý là dữ liệu không bắt đầu từ 0:

# mdadm -E /dev/raidme/rd0 | grep "Data Offset"
    Data Offset : 4096 sectors

Vì vậy, printf "%x\n" $(((4096+16384)*512))nói rằng đó 0xa00000là tốt. Tốt


Chặn trong md

Bây giờ để có được vị trí ở cuối md, thực sự dễ dàng hơn: đơn giản là vị trí được đưa ra trong thời gian của ngành, number_of_stripesví dụ với tôi, tôi có 4 đĩa (3 + 1) nên có 3 sọc.

Ở đây, nó có nghĩa là 16384*3*512ví dụ 0x1800000. Tôi đã lấp đầy đĩa khá tốt để dễ dàng kiểm tra chỉ cần đọc đĩa và tìm kiếm 1k số không:

# dd if=/dev/md127 bs=1M | hexdump -C | grep -C 3 '00 00 00 00 00 00'
... some false positives...
01800000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
01800400  6b a8 9e e0 ad 88 a8 de  dd 2e 68 00 d8 7a a3 52  |k.........h..z.R|

Chặn trong xfs

Mát mẻ. Bây giờ chúng ta hãy xem đó là nơi trong xfs. 16384*349152(daddr lấy số ngành):

# xfs_db -r /dev/md127
xfs_db> blockget -n
xfs_db> daddr 49152
xfs_db> blockuse -n
block 6144 (0/6144) type data inode 2052 d.1/f.1

Chắc chắn, các số 0 nằm trong tệp đó:

# dd if=/mnt/d.1/f.1 bs=1M | hexdump -C | grep -C 3 '00 00 00 00 00'
...
03680000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
03680400  6b a8 9e e0 ad 88 a8 de  dd 2e 68 00 d8 7a a3 52  |k.........h..z.R|

Nếu chúng ta ghi đè lên tệp đó, các số 0 sẽ biến mất trong / dev / raidme / rd0 ở phần bù chính xác (chỉ cần dd nó với một tệp khác). Nếu bạn viết lại trong / dev / raidme / rd0 (đảm bảo bạn dừng / bắt đầu lại mảng) thì các số 0 đã trở lại. Có vẻ tốt.

Mặc dù vậy, có một vấn đề nữa, nếu kích thước sọc của bạn lớn như của tôi ở đây (512k), thì chúng tôi không có một khối duy nhất để xử lý nhưng 1,5 MB dữ liệu có thể bị hỏng ... Thường thì sẽ đủ trong một tập tin duy nhất, nhưng bạn cần kiểm tra xem, quay lại xfs_db. Nhớ inode trước đó là năm 2052.

xfs_db> inode 2052
xfs_db> bmap
data offset 0 startblock 256 (0/256) count 17536 flag 0
data offset 17536 startblock 122880 (0/122880) count 4992 flag 0
data offset 22528 startblock 91136 (0/91136) count 3072 flag 0

Một khối có kích thước 4096 byte ở đây (xem xfs_info), vì vậy 1,5 MB của chúng tôi là 384 khối. Phân đoạn bị hỏng của chúng tôi là khối 6144 đến 6528 - cũng nằm trong phân khúc đầu tiên của tệp này.

Một cái gì đó khác để xem xét là trích xuất các khối bằng tay và kiểm tra chính xác vị trí của tổng kiểm không khớp, hy vọng sẽ cung cấp cho bạn 3 khối nhỏ hơn để xem xét.


Cuối cùng về bản vá của bạn, bản thân tôi không phải là một md dev mà là một người dùng ex-mdadm raid5, tôi sẽ rất thích thú. Tôi muốn nói rằng nó chắc chắn xứng đáng với nỗ lực để đẩy nó vào một chút. Việc dọn dẹp mà bạn đề cập có thể hữu ích và tôi chắc chắn các nhà phát triển sẽ có một số nhận xét sau khi bạn gửi một bản vá, nhưng md md cần phải dài dòng hơn về những lỗi này!


Huh, tôi rất vui vì bạn đã chỉ ra vị trí trên các thiết bị khối bên dưới. Trong trường hợp của tôi, printf '%#x\n' $(( (259072+4294708224 )*512 ))0x20000000000, mà rõ ràng không phải là một trùng hợp ngẫu nhiên. (Đó chính xác là 2TiB. Tôi nghi ngờ một số shenanigans từ cài đặt grub hoặc một loại điều MBR nào đó). Tôi sẽ không nhận thấy điều này nếu tôi chỉ nhìn vào phần bù trong thiết bị MD để tìm tệp bị ảnh hưởng. (BTW, %#xđịnh dạng thêm 0xtiền tố cho bạn.)
Peter Cordes

xfs_dbchỉ nói must run blockget first, mặc dù tôi vừa mới làm (chính xác như tôi đã đăng trong câu hỏi), sau khi làm theo ví dụ của bạn. Ngay cả khi tôi sử dụng blockget -v -n -b 12884124672để cung cấp cho nó một khối cụ thể. Tôi đã sử dụng ddhexdumpđể thấy rằng thực sự có một sự không phù hợp ở khối đó. Ba là 0 và thứ tư có một bit đơn được đặt ở mức 1kiB thành dải 512k. (Rất thuận tiện khi tôi không phải tìm cách thực sự chặn các khối XOR để kiểm tra sự dư thừa.)
Peter Cordes

Nếu tôi sử dụng daddrđầu tiên (trước blockget), tôi sẽ không nhận được thông báo lỗi, chỉ là không có đầu ra nào cả blockget -v -nblockuse -v -n. Trong trường hợp có vấn đề, xfspross của tôi là 3.2.1ubfox1 và tôi đang sử dụng Linux 4.2.0-36-generic (không phải kernel -rc đã vá của tôi). FS của tôi đang sử dụng crc=1 isize=512, naming =version 2 bsize=4096 ascii-ci=0 ftype=1
Peter Cordes

Dù sao, câu trả lời này không xác định chính xác vị trí của khối không khớp trên các thiết bị thành phần và trên thiết bị md. Phần duy nhất không hoạt động là khối XFS-> phần tên tệp, đây thực sự là một câu hỏi riêng biệt. Về lý thuyết tôi có thể sử dụng find -exec xfs_bmap -vpl {} +để tìm kiếm một tập tin có chứa khối đã biết.
Peter Cordes

1
Rất tiếc, tôi không biết bất kỳ cách nào để làm cho xfs_db bỏ qua nhật ký nhật ký (ví dụ: chặn blockget ngay cả khi không nhất quán 100%) hoặc làm cho kernel "tuôn ra" mà nhật ký như một umount / mount sẽ làm và làm cho xfs_db hài lòng. .. Vì vậy, trừ khi bạn muốn loại bỏ một cái gì đó, nó có thể cần phải chờ một chút cho đến khi bạn có thể kể lại. Luôn cập nhật cho tôi và đừng quên cố gắng ngược dòng bản vá đó :)
Ascraftus
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.