?? ide-error-reporting
字號:
# HG changeset patch# User kfraser@localhost.localdomain# Node ID fd28a1b139dea91b8bfcf06dd233dbdda8f51ff1# Parent d8befb109c394c2c2d3e1870a500107d461724ef[QEMU] Error reporting in IDE device model.Following on from my patch to make blktap report I/O errors back toguest OS, a similar problem exists in the QEMU codebase. The IDEdriver never reports I/O errors during read/write operations back tothe guest OS. Instead all I/O operations are reported assuccesfull. If, for example, the host FS holding the disk image fillsup, then writes may fail due to lack of space. Since the guest OSnever sees these failures, it assumes all is well & will continuewriting. Eventually this can lead to severe & unrecoverable filesystemcorruption.The attached patch fixes QEMU ide driver such that any failure of aread or write operation sets the appropriate IDE status/errorregisters. Having read the ATA-6 spec I think the most compliantbehaviour is to set the status register to 'READY_STAT | ERR_STAT',and the error register to ABRT_ERR. There is already a conveniencefunction ide_abort_command() in the QEMU codebase which does justthis, so the attached patch simply calls that function.With this patch the guest OS sees the I/O failure & the kernel logsIDE errors and then retries the operation. This at least ensures thatthe guest can be shutdown the out of space issue in the host correctedand the guest restarted, without any serious filesystem damage havingoccurred.From: Daniel Berrange <berrange@redhat.com>Signed-off-by: Keir Fraser <keir@xensource.com>Index: ioemu/hw/ide.c===================================================================--- ioemu.orig/hw/ide.c 2007-05-03 20:38:33.000000000 +0100+++ ioemu/hw/ide.c 2007-05-03 20:45:33.000000000 +0100@@ -767,7 +767,7 @@ static void ide_sector_read(IDEState *s) { int64_t sector_num;- int ret, n;+ int n; s->status = READY_STAT | SEEK_STAT; s->error = 0; /* not needed by IDE spec, but needed by Windows */@@ -782,7 +782,11 @@ #endif if (n > s->req_nb_sectors) n = s->req_nb_sectors;- ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);+ if (bdrv_read(s->bs, sector_num, s->io_buffer, n) != 0) {+ ide_abort_command(s);+ ide_set_irq(s);+ return;+ } ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read); ide_set_irq(s); ide_set_sector(s, sector_num + n);@@ -899,7 +903,7 @@ static void ide_sector_write(IDEState *s) { int64_t sector_num;- int ret, n, n1;+ int n, n1; s->status = READY_STAT | SEEK_STAT; sector_num = ide_get_sector(s);@@ -909,7 +913,11 @@ n = s->nsector; if (n > s->req_nb_sectors) n = s->req_nb_sectors;- ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);+ if (bdrv_write(s->bs, sector_num, s->io_buffer, n) != 0) {+ ide_abort_command(s);+ ide_set_irq(s);+ return;+ } s->nsector -= n; if (s->nsector == 0) { /* no more sector to write */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -