TL; Ringkasan DR : Terjemahkan nomor sektor md ke dalam offset di dalam /dev/mdX
perangkat, dan bagaimana cara menyelidikinya xfs_db
. Nomor sektor berasal dari sh->sector
dalam linux/drivers/md/raid5.c:handle_parity_checks5()
.
Saya tidak tahu internal MD, jadi saya tidak tahu persis apa yang harus dilakukan dengan output dari printk
logging yang saya tambahkan.
Offset ke perangkat komponen (untuk dd
atau hex editor / viewer) juga akan menarik.
Saya kira saya harus menanyakan ini di milis Linux-raid. Apakah hanya pelanggan, atau bisakah saya memposting tanpa berlangganan?
Saya memiliki xfs langsung di atas MD RAID5 dari 4 disk di desktop saya (tidak ada LVM). Lulur baru-baru ini mendeteksi non-nol mismatch_cnt
(8 pada kenyataannya, karena md beroperasi pada halaman 4kiB sekaligus).
Ini adalah RAID5, bukan RAID1 / RAID10 di mana mismatch_cnt
! = 0 dapat terjadi selama operasi normal . (Tautan lain di bagian bawah halaman wiki ini mungkin berguna bagi sebagian orang.)
Saya hanya bisa membabi buta repair
, tapi kemudian saya tidak tahu file mana untuk memeriksa kemungkinan korupsi, selain kehilangan kesempatan untuk memilih cara merekonstruksi mana. Jawaban Frostschutz pada pertanyaan serupa adalah satu-satunya saran yang saya temukan untuk melacak kembali perbedaan dalam sistem file. Ini rumit dan lambat, dan saya lebih suka menggunakan sesuatu yang lebih baik untuk mempersempitnya menjadi beberapa file terlebih dahulu.
Patch kernel untuk menambahkan logging
Anehnya, fitur cek md tidak melaporkan di mana kesalahan ditemukan . Saya menambahkan printk
di md / raid5.c untuk login sh->sector
di if
cabang yang bertahap mddev->resync_mismatches
dalamhandle_parity_checks5()
(sepetak kecil yang diterbitkan pada github , awalnya didasarkan pada 4,5-RC4 dari kernel.org.) Untuk ini ok untuk penggunaan umum, mungkin akan perlu hindari membanjiri log dalam perbaikan dengan banyak ketidakcocokan (mungkin hanya login jika nilai baru resync_mismatches
<1000?). Mungkin juga hanya masuk check
dan tidak repair
.
Saya cukup yakin saya mencatat sesuatu yang bermanfaat (walaupun saya tidak tahu MD internal!), Karena fungsi yang sama mencetak nomor sektor dalam kasus penanganan kesalahan dariswitch
.
Saya mengkompilasi kernel yang dimodifikasi dan mem-boot-nya, lalu menjalankan ulang pemeriksaan:
[ 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.
Sekarang saya tidak tahu persis apa yang harus dilakukan dengan nomor sektor itu. Apakah sh->sector * 512
alamat linear di dalam /dev/md/t-r5
(alias /dev/md125
)? Apakah ini nomor sektor dalam setiap perangkat komponen (jadi ini mengacu pada tiga data dan satu sektor paritas)? Saya menduga yang terakhir, karena paritas-ketidakcocokan dalam RAID5 berarti N-1 sektor perangkat md berada dalam bahaya, diimbangi satu sama lain oleh unit stripe. Apakah sektor 0 merupakan permulaan dari perangkat komponen, atau apakah itu sektor setelah superblok atau semacamnya? Apakah ada informasi lebih lanjut handle_parity_checks5()
yang seharusnya saya hitung / login?
Jika saya hanya ingin mendapatkan blok yang tidak cocok, apakah ini benar?
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
Saya kira tidak, karena saya mendapatkan 4k nol dari keempat komponen serangan, dan 0^0 == 0
, sehingga harus menjadi paritas yang benar, bukan?
Satu tempat lain yang pernah saya lihat menyebutkan menggunakan alamat sektor dalam md adalah untuk sync_min
dan sync_max
(dalam sysfs). Neil Brown di daftar linux-raid , dalam menanggapi pertanyaan tentang drive yang gagal dengan nomor sektor dari hdrecover
, di mana Neil menggunakan nomor sektor disk penuh sebagai nomor sektor MD. Itu tidak benar kan? Bukankah angka sektor md relatif terhadap perangkat komponen (partisi dalam kasus itu), bukan perangkat lengkap yang menjadi bagian dari partisi?
sektor linear ke nama file XFS:
Sebelum menyadari bahwa nomor sektor md mungkin untuk komponen, bukan perangkat RAID, saya mencoba menggunakannya dalam read-only xfs_db
:
Saran yang sangat singkat dari Dave Chinner tentang bagaimana menemukan bagaimana XFS menggunakan blok yang diberikan tampaknya tidak bekerja sama sekali untuk saya. (Saya akan mengharapkan semacam hasil, untuk beberapa sektor, karena jumlahnya tidak boleh melebihi akhir perangkat bahkan jika itu bukan sektor yang tidak cocok)
# 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
Hah? Apa yang saya lakukan salah di sini? Saya kira ini harus menjadi pertanyaan terpisah. Saya akan mengganti ini dengan tautan jika / ketika saya bertanya atau menemukan jawaban untuk bagian ini di tempat lain.
RAID5 saya pada dasarnya idle, tanpa aktivitas tulis dan minimal baca (dan noatime
, jadi baca tidak menghasilkan penulisan).
Banyak hal tambahan tentang pengaturan saya, tidak ada yang penting di sini
Banyak file saya adalah video atau data terkompresi lainnya yang memberikan cara efektif untuk mengetahui apakah data itu benar atau tidak (baik checksum internal dalam format file, atau hanya apakah itu diterjemahkan tanpa kesalahan). Itu akan membuat metode loopback read-only ini layak, setelah saya tahu file mana yang harus diperiksa. Saya tidak ingin menjalankan diff 4-arah dari setiap file di sistem file untuk menemukan ketidakcocokan pertama, ketika kernel memiliki informasi yang diperlukan saat memeriksa, dan dapat dengan mudah mencatatnya.
my /proc/mdstat
untuk array data massal saya:
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
Ada di partisi pada tiga drive Toshiba 3TB, dan drive hijau (lambat) WD25EZRS non-partisi yang saya ganti dengan Toshiba lain. (Menggunakan mdadm --replace
untuk melakukannya secara online tanpa celah dalam redundansi. Saya menyadari setelah satu salinan bahwa saya harus memeriksa kesehatan RAID sebelum dan sesudahnya, untuk mendeteksi masalah. Saat itulah saya mendeteksi ketidakcocokan. Mungkin sudah ada sejak lama. , sejak saya mengalami crash hampir setahun yang lalu, tapi saya tidak punya log lama dan mdadm sepertinya tidak mengirim email tentang ini secara default (Ubuntu 15.10).
Filesystem saya yang lain menggunakan perangkat RAID10f2 yang dibuat dari partisi sebelumnya pada tiga HD yang lebih besar (dan RAID0 untuk / var / tmp). RAID5 hanya untuk penyimpanan massal, bukan /home
atau /
.
Drive saya baik-baik saja: jumlah kesalahan SMART adalah 0 semua penghitung blok buruk pada semua drive, dan tes mandiri SMART pendek + panjang berlalu.
duplikat dekat dari pertanyaan ini yang tidak memiliki jawaban:
- Potongan apa yang tidak cocok dalam larik md Linux?
- http://www.spinics.net/lists/raid/msg49459.html
- MDADM mismatch_cnt> 0. Apakah ada cara untuk mengidentifikasi blok mana yang tidak setuju?
- Hal-hal lain sudah ditautkan secara inline, tetapi terutama ide loopback read-only frostschutz .
- menggosok pada halaman Arch wiki RAID
sumber
mdadm -E /dev/xxx
..damaged
atau sesuatu, daripada hanya tahu mungkin ada file yang rusak di suatu tempat.Jawaban:
Sektor TL; DR sh-> adalah jumlah sektor dalam disk fisik setelah dimulainya bagian data
Mendirikan
Berikut ini adalah pengaturan uji sederhana untuk menggambarkan:
Sekarang untuk memulai, dapatkan blok bukan nol dan timpa
Pastikan cache dm / md memerah dengan menghentikan / memasang kembali array, dan periksa:
Blokir di disk
Oke, jadi pertama mari kita periksa 16384 cocok dengan apa yang kami tulis. Serangan saya memiliki garis 512k jadi saya memastikan saya menulis sesuatu yang selaras agar mudah dicocokkan, kami menulis di
1024*10240
mis0xa00000
.Tambalan Anda memberikan info
16384
, satu hal yang perlu diperhatikan adalah bahwa data tidak dimulai pada 0:Jadi
printf "%x\n" $(((4096+16384)*512))
mengatakan itu0xa00000
juga. Baik.Blokir di md
Sekarang untuk mendapatkan yang ada di ujung md, sebenarnya lebih mudah: itu hanya posisi yang diberikan di sektor kali
number_of_stripes
misalnya untuk saya, saya punya 4 disk (3 +1) jadi 3 garis.Di sini, itu berarti
16384*3*512
mis0x1800000
. Saya mengisi disk dengan cukup baik sehingga mudah untuk memeriksa hanya membaca disk dan mencari 1r nol:Blokir dalam xfs
Keren. Mari kita lihat di mana xfs berada sekarang.
16384*3
is49152
(daddr mengambil nomor sektor):Tentunya, angka nol ada di file itu:
Jika kita menimpa file itu, nolnya akan ada di / dev / raidme / rd0 di offset yang benar juga (cukup lakukan dengan file lain). Jika Anda menulis di / dev / raidme / rd0 lagi (pastikan Anda menghentikan / memulai array lagi) maka nolnya kembali. Kelihatan bagus.
Namun ada satu masalah lagi, jika ukuran garis Anda sebesar milik saya di sini (512k), maka kami tidak memiliki satu blok untuk menangani tetapi 1,5MB dari data yang mungkin rusak ... Cukup sering itu akan berada dalam satu file, tetapi Anda perlu memeriksanya, kembali di xfs_db. Ingat inode sebelumnya adalah 2052.
Satu blok berukuran 4096 byte di sini (lihat
xfs_info
), jadi 1.5MB kami adalah 384 blok. Segmen rusak kami adalah blok 6144 hingga 6528 - baik di dalam segmen pertama dari file ini.Sesuatu yang lain untuk dilihat adalah mengekstraksi blok dengan tangan dan memeriksa di mana tepatnya checksum tidak cocok, yang diharapkan akan memberi Anda 3 potongan kecil untuk dilihat.
Terakhir tentang tambalan Anda, saya bukan md dev sendiri, tetapi sebagai pengguna raid5 mantan mdadm, saya akan sangat tertarik. Saya akan mengatakan itu sepadan dengan usaha untuk mendorongnya sedikit. Pembersihan yang Anda sebutkan mungkin berguna dan saya yakin para devs akan memiliki beberapa komentar setelah Anda mengirimkan tambalan, tetapi huh md perlu lebih bertele-tele tentang kesalahan ini!
sumber
printf '%#x\n' $(( (259072+4294708224 )*512 ))
adalah0x20000000000
, yang jelas bukan suatu kebetulan. (Tepatnya itu adalah 2TiB. Saya menduga ada shenanigans dari grub-install atau semacam MBR). Saya tidak akan memperhatikan ini jika saya hanya melihat offset dalam perangkat MD untuk menemukan file yang terpengaruh. (BTW,%#x
format menambahkan0x
awalan untuk Anda.)xfs_db
hanya mengatakanmust run blockget first
, meskipun saya baru saja melakukannya (persis seperti yang saya posting di pertanyaan), setelah mengikuti contoh Anda. Bahkan jika saya gunakanblockget -v -n -b 12884124672
untuk memberikannya blok tertentu. Saya menggunakandd
danhexdump
menemukan bahwa sebenarnya ada ketidakcocokan di blok itu. Tiga semuanya nol, dan yang keempat memiliki satu bit ditetapkan pada 1kiB ke dalam garis 512k. (Sangat mudah bahwa saya tidak perlu menemukan cara untuk benar-benar blok XOR untuk memeriksa redundansi.)daddr
pertama (sebelum blockget), saya tidak mendapatkan pesan kesalahan, hanya saja tidak ada output sama sekali dariblockget -v -n
danblockuse -v -n
. Dalam hal ini penting, xfsprogs saya adalah 3.2.1ubuntu1, dan saya menggunakan Linux 4.2.0-36-generic (bukan kernel -rc patched saya). FS saya gunakancrc=1 isize=512
,naming =version 2 bsize=4096 ascii-ci=0 ftype=1
find -exec xfs_bmap -vpl {} +
untuk mencari file yang berisi blok yang dikenal.