Kasıtlı olarak Linux'ta bir G / Ç hatasına neden olur?


42

Yine de, Linux ile, bir blok aygıtın bir G / Ç hatası bildirmesine veya muhtemelen test amacıyla birini simüle etmesine neden olacak şekilde var mı?


Bir disk arızası taklit ediyor musunuz? Belki bir dizin bağlayabilir ve kullanımdayken bağlantısını kesebilirsiniz.
Shef

2
Yükleyebileceğiniz küçük bir çekirdek modülü yazar, modprobebir blok aygıtı gibi davranır ve ardından ioctl()'ssürücüye istediğiniz değeri döndürmesini sağlayan başka bir küçük program yazardım .
ott--


@Gilles'in yaptığı yorumu takip etmek için, aynı zamanda stackoverflow.com/questions/1361518/… (birkaç farklı hata enjeksiyon yanıtı) ve stackoverflow.com/questions/1870696/… (cihaz eşleştiricisini kullanın ) sorulmuştur .
Anon

Yanıtlar:


54

Evet, bunu cihaz eşleyicisiyle yapmanın çok makul bir yolu var.

Cihaz eşleyici, blok cihazlarınızı seçtiğiniz bir yeni eşleme / sırayla birleştirebilir. LVM bunu yapar. Ayrıca, arızalı bir diski taklit etmek için 'flakey' ve diskin başarısız bölgelerini taklit etmek için 'hata' gibi diğer hedefleri (bazıları oldukça yeni olan) destekler.

Biri, kasıtlı olarak IO kara deliklerine sahip bir cihaz oluşturabilir ve üzerinde IO hatalarını rapor eder.

İlk önce, hedef olarak kullanmak için bir sanal birim oluşturun ve bunu blok cihaz olarak adreslenebilir hale getirin.

dd if=/dev/zero of=/var/lib/virtualblock.img bs=512 count=1048576
losetup /dev/loop0 /var/lib/virtualblock.img

Bu nedenle, bunu başlatmak için sanal blok aygıtımızın temeli olan 512M bir dosya oluşturulur ve bu sırada bir 'delik' açacağız. Henüz bir delik yok. Yerinde olsaydın, mkfs.ext4 /dev/loop0geçerli bir dosya sistemi elde edersin.

Öyleyse, bu blok cihazını kullanarak - içinde bazı delikleri olan yeni bir cihaz yaratacak olan dmsetup kullanalım. İşte ilk örnek

dmsetup create errdev0
0 261144 linear /dev/loop0 0
261144 5 error
261149 787427 linear /dev/loop0 261139

Bu 'errdev0' adında bir cihaz yaratacaktır (genellikle / dev / mapper içinde). Yazdığınızda dmsetup create errdev0stdin için bekleyecek ve ^ D girişi olacak.

Yukarıdaki örnekte, döngü cihazının 261144 sektörlerinde 5 sektör boşluğu (2.5kb) yaptık. Daha sonra loop cihaz üzerinden normal şekilde devam ediyoruz.

Bu komut dosyası, yaklaşık 16Mb civarında dağılmış rasgele konumlara delikler açacak bir tablo oluşturmaya çalışacaktır (oldukça rastgele olmasına rağmen).

#!/bin/bash
start_sector=0
good_sector_size=0

for sector in {0..1048576}; do

    if [[ ${RANDOM} == 0 ]]; then
        echo "${start_sector} ${good_sector_size} linear /dev/loop0 ${start_sector}"
        echo "${sector} 1 error"
        start_sector=$((${sector}+1))
        good_sector_size=0
    else
        good_sector_size=$((${good_sector_size}+1))
    fi
done

echo "${start_sector} $((${good_sector_size}-1)) linear /dev/loop0 ${start_sector}"

Betik ayrıca bir 512Mb cihaz oluşturduğunuzu ve sanal blok cihazınızın açık olduğunu varsayar /dev/loop0.

Bu verileri yalnızca bir metin dosyasına tablo olarak yazdırabilir ve içine aktarabilirsiniz dmsetup create errdev0.

Cihazı bir kez yarattıktan sonra, normal bir blok cihaz gibi kullanmaya başlayabilirsiniz, önce onu biçimlendirerek ve sonra üzerine dosyalar yerleştirerek. Bir noktada sanal cihazda gerçekten IO delikleri olan sektörlere çarptığınız bazı IO problemleriyle karşılaşmalısınız.

İşiniz bittiğinde dmsetup remove errdev0cihazı çıkarmak için kullanın .

Bir GÇ hatası alma olasılığını artırmak istiyorsanız, daha sık delikler ekleyebilir veya oluşturduğunuz deliklerin boyutunu değiştirebilirsiniz. Hataların bazı bölümlere yerleştirilmesinin, başlangıçta 32 MB’de IE’nin sıkıntılarına neden olacağına dikkat edin, ext normalde yapmaya çalışan bir süper blok yazamazsınız, bu nedenle format çalışmaz.

Daha fazla eğlence için - aslında sadece losetupo zaman mkfs.ext4 /dev/loop0ve verilerle doldurun. Orada güzel bir çalışma dosya sistemine sahip olduğunuzda, dosya sisteminin bağlantısını kesin ve dmsetup kullanarak bazı delikler ekleyin ve bunu yeniden kurun!


6
Bunu yapabileceğini bilmiyordum. Oldukça havalı.

15

Çıktılarının başarısız olması durumunda programın sağlamlığını kontrol etmek için /dev/full, yazıldığında her zaman "ENOSPACE" değerini döndüren sahte modülü kullanabilirsiniz.

$ dd if=/dev/zero of=/dev/full
dd: writing to `/dev/full': No space left on device
1+0 records in
0+0 records out

7

Ne test etmek istediğine bağlı. Bir LD_PRELOADed kütüphanesini kullanarak , örneğin 'bütün yazarların başarısız olduğu ENOSPCveya EIO' gibi şeyleri düşünerek uygulamaları kandırabilirsiniz .



1

Belki de bölüm tablosunu değiştirebilir ve bölümün gerçekten olduğundan daha büyük olmasını sağlayabilirsiniz. Bu muhtemelen bir g / Ç hatasına neden olur. Veya diskleriniz takılabilir durumda ise, yalnızca bir tane çıkarabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.