Cố tình gây ra lỗi I / O trong Linux?


42

Có cách nào, với Linux, cố tình khiến một thiết bị khối báo cáo lỗi I / O hoặc có thể mô phỏng một lỗi cho mục đích thử nghiệm không?


Bạn đang mô phỏng một lỗi đĩa? Có lẽ bạn có thể gắn một thư mục và sau đó ngắt kết nối nó trong khi nó đang được sử dụng.
Shef

2
Tôi sẽ viết một mô-đun hạt nhân nhỏ mà bạn có thể tải cùng modprobe, hoạt động như một thiết bị khối và sau đó một chương trình nhỏ khác gửi ioctl()'sđến trình điều khiển để làm cho nó trả về giá trị bạn muốn.
ott--


Để theo dõi nhận xét @Gilles đã đưa ra, điều này cũng đã được hỏi trên stackoverflow.com/questions/1361518/ (một số câu trả lời tiêm lỗi khác nhau) và stackoverflow.com/questions/1870696/ (sử dụng trình ánh xạ thiết bị).
Anon

Câu trả lời:


54

Có, có một cách rất hợp lý để làm điều này với trình ánh xạ thiết bị.

Trình ánh xạ thiết bị có thể kết hợp lại các thiết bị chặn thành một ánh xạ / thứ tự mới mà bạn chọn. LVM làm điều này. Nó cũng hỗ trợ các mục tiêu khác, (một số khá mới lạ) như 'flakey' để mô phỏng một đĩa bị lỗi và 'lỗi' để mô phỏng các vùng đĩa bị lỗi.

Người ta có thể xây dựng một thiết bị có chủ ý có các lỗ đen IO trên đó sẽ báo cáo lỗi IO khi vượt qua.

Đầu tiên, tạo một số âm lượng ảo để sử dụng làm mục tiêu và làm cho nó có thể định địa chỉ như một thiết bị khối.

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

Vì vậy, để bắt đầu điều này, hãy tạo một tệp 512M, là nền tảng của thiết bị khối ảo mà chúng tôi sẽ đục một 'lỗ'. Mặc dù vậy vẫn chưa có lỗ hổng nào. Nếu bạn đã mkfs.ext4 /dev/loop0có một hệ thống tập tin hoàn toàn hợp lệ.

Vì vậy, hãy sử dụng dmsetup, sử dụng thiết bị khối này - sẽ tạo ra một thiết bị mới có một số lỗ hổng trong đó. Đây là một ví dụ đầu tiên

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

Điều này sẽ tạo ra một thiết bị gọi là 'errdev0' (thường là trong / dev / mapper). Khi bạn gõ dmsetup create errdev0nó sẽ đợi stdin và sẽ kết thúc vào ^ D là đầu vào.

Trong ví dụ trên, chúng tôi đã tạo ra một lỗ 5 khu vực (2,5kb) tại các khu vực 261144 của thiết bị vòng lặp. Chúng tôi sau đó tiếp tục thông qua các thiết bị vòng lặp như bình thường.

Kịch bản lệnh này sẽ cố gắng tạo cho bạn một bảng sẽ đặt các lỗ ở các vị trí ngẫu nhiên xấp xỉ khoảng 16Mb (mặc dù nó khá ngẫu nhiên).

#!/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}"

Kịch bản giả định rằng bạn cũng đã tạo một thiết bị 512Mb và thiết bị khối ảo của bạn được bật /dev/loop0.

Bạn chỉ có thể xuất dữ liệu này thành tệp văn bản dưới dạng bảng và dẫn dữ liệu vào dmsetup create errdev0.

Khi bạn đã tạo thiết bị, bạn có thể bắt đầu sử dụng nó như một thiết bị khối bình thường, đầu tiên bằng cách định dạng thiết bị và sau đó bằng cách đặt các tệp trên thiết bị. Tại một số điểm, bạn sẽ gặp một số vấn đề về IO khi bạn gặp phải các lỗ hổng IO thực sự trong thiết bị ảo.

Khi bạn đã sử dụng xong dmsetup remove errdev0để tháo thiết bị.

Nếu bạn muốn làm cho nó có nhiều khả năng bị lỗi IO, bạn có thể thêm các lỗ thường xuyên hơn hoặc thay đổi kích thước của các lỗ bạn tạo. Lưu ý đặt lỗi trong một số phần nhất định có thể gây ra sự cố khi di chuyển, IE ở mức 32mb vào thiết bị bạn không thể viết một siêu khối mà ext thường cố gắng thực hiện, vì vậy định dạng sẽ không hoạt động ..

Để thêm phần thú vị - bạn thực sự có thể ngay losetupsau đó mkfs.ext4 /dev/loop0và điền nó với dữ liệu. Khi bạn đã có một hệ thống tệp hoạt động tốt ở đó, chỉ cần ngắt kết nối hệ thống tệp và thêm một số lỗ hổng bằng cách sử dụng dmsetup và kể lại điều đó!


6
Tôi không biết bạn có thể làm điều này. Tuyệt đấy.

15

Để kiểm tra độ mạnh của chương trình trong trường hợp đầu ra của chúng không thành công, bạn có thể sử dụng giả mã /dev/full, luôn trả về "ENOSPACE" khi được ghi vào.

$ 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

Phụ thuộc vào những gì bạn muốn kiểm tra. Sử dụng một LD_PRELOADthư viện ed, bạn có thể lừa các ứng dụng suy nghĩ những điều như 'tất cả ghi đều thất bại với ENOSPChoặc EIO' chẳng hạn.



1

Có lẽ bạn có thể thay đổi bảng phân vùng và làm cho phân vùng lớn hơn thực sự. Điều đó có thể sẽ gây ra lỗi i / o. Hoặc nếu đĩa của bạn đang cắm nóng, bạn có thể lấy ra.

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.