Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > media > main-src > by-pkgid > aadbe78a25743146bb784eee19f007c5 > files > 303

kvm-83-164.el5_5.9.src.rpm

From 3bd0ed364f053a889b5914917369bd93637cc592 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Tue, 24 Nov 2009 19:43:07 -0200
Subject: [PATCH 07/11] ide: Stop VM on read errors

RH-Author: Kevin Wolf <kwolf@redhat.com>
Message-id: <1258367498-9527-3-git-send-email-kwolf@redhat.com>
Patchwork-id: 3723
O-Subject: [RHEL-5.5 KVM PATCH v2 2/2] ide: Stop VM on read errors
Bugzilla: 531827 533390
RH-Acked-by: Juan Quintela <quintela@redhat.com>
RH-Acked-by: Gleb Natapov <gleb@redhat.com>
RH-Acked-by: Markus Armbruster <armbru@redhat.com>

Bugzilla: 531827
Upstream status: Needs to be solved differently (changes semantics of werror)

The VM should not only be stopped on write errors but also on read errors as
they can confuse the guest as well (e.g. remounting the root file system
read-only during a host NFS outage when the disk image is on NFS).

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu/hw/ide.c |   51 ++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 36 insertions(+), 15 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qemu/hw/ide.c |   51 ++++++++++++++++++++++++++++++++++++---------------
 1 files changed, 36 insertions(+), 15 deletions(-)

diff --git a/qemu/hw/ide.c b/qemu/hw/ide.c
index 4f98428..abc6b10 100644
--- a/qemu/hw/ide.c
+++ b/qemu/hw/ide.c
@@ -463,6 +463,7 @@ static inline int media_is_cd(IDEState *s)
 #define BM_STATUS_INT    0x04
 #define BM_STATUS_DMA_RETRY  0x08
 #define BM_STATUS_PIO_RETRY  0x10
+#define BM_STATUS_RETRY_READ  0x20
 
 #define BM_CMD_START     0x01
 #define BM_CMD_READ      0x08
@@ -507,8 +508,9 @@ typedef struct PCIIDEState {
 } PCIIDEState;
 
 static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
-static void ide_dma_restart(IDEState *s);
+static void ide_dma_restart(IDEState *s, int is_read);
 static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
+static int ide_handle_rw_error(IDEState *s, int error, int op);
 
 static void padstr(char *str, const char *src, int len)
 {
@@ -857,8 +859,11 @@ static void ide_sector_read(IDEState *s)
             n = s->req_nb_sectors;
         ret = bdrv_read(s->bs, sector_num, s->io_buffer, n);
         if (ret != 0) {
-            ide_rw_error(s);
-            return;
+            if (ide_handle_rw_error(s, -ret,
+                BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ))
+            {
+                return;
+            }
         }
         ide_transfer_start(s, s->io_buffer, 512 * n, ide_sector_read);
         ide_set_irq(s);
@@ -875,7 +880,7 @@ static void ide_dma_error(IDEState *s)
     ide_set_irq(s);
 }
 
-static int ide_handle_write_error(IDEState *s, int error, int op)
+static int ide_handle_rw_error(IDEState *s, int error, int op)
 {
     BlockInterfaceErrorAction action = drive_get_onerror(s->bs);
 
@@ -892,7 +897,7 @@ static int ide_handle_write_error(IDEState *s, int error, int op)
 			bdrv_get_device_name(s->bs), strerror(error));
         term_printf_async(VMSTOP_ASYNC_EVENT, "%s\n", vm_stop_reason);
     } else {
-        if (op == BM_STATUS_DMA_RETRY)
+        if (op & BM_STATUS_DMA_RETRY)
             ide_dma_error(s);
         else
             ide_rw_error(s);
@@ -957,8 +962,11 @@ static void ide_read_dma_cb(void *opaque, int ret)
     int64_t sector_num;
 
     if (ret < 0) {
-	ide_dma_error(s);
-	return;
+        if (ide_handle_rw_error(s, -ret,
+            BM_STATUS_DMA_RETRY | BM_STATUS_RETRY_READ))
+        {
+            return;
+        }
     }
 
     n = s->io_buffer_size >> 9;
@@ -1028,7 +1036,7 @@ static void ide_sector_write(IDEState *s)
     ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
 
     if (ret != 0) {
-        if (ide_handle_write_error(s, -ret, BM_STATUS_PIO_RETRY))
+        if (ide_handle_rw_error(s, -ret, BM_STATUS_PIO_RETRY))
             return;
     }
 
@@ -1064,16 +1072,23 @@ static void ide_sector_write(IDEState *s)
 static void ide_dma_restart_bh(void *opaque)
 {
     BMDMAState *bm = opaque;
+    int is_read;
 
     qemu_bh_delete(bm->bh);
     bm->bh = NULL;
 
+    is_read = !!(bm->status & BM_STATUS_RETRY_READ);
+
     if (bm->status & BM_STATUS_DMA_RETRY) {
-        bm->status &= ~BM_STATUS_DMA_RETRY;
-        ide_dma_restart(bm->ide_if);
+        bm->status &= ~(BM_STATUS_DMA_RETRY | BM_STATUS_RETRY_READ);
+        ide_dma_restart(bm->ide_if, is_read);
     } else if (bm->status & BM_STATUS_PIO_RETRY) {
-        bm->status &= ~BM_STATUS_PIO_RETRY;
-        ide_sector_write(bm->ide_if);
+        bm->status &= ~(BM_STATUS_PIO_RETRY | BM_STATUS_RETRY_READ);
+        if (is_read) {
+            ide_sector_read(bm->ide_if);
+        } else {
+            ide_sector_write(bm->ide_if);
+        }
     }
 }
 
@@ -1098,7 +1113,7 @@ static void ide_write_dma_cb(void *opaque, int ret)
     int64_t sector_num;
 
     if (ret < 0) {
-        if (ide_handle_write_error(s, -ret,  BM_STATUS_DMA_RETRY))
+        if (ide_handle_rw_error(s, -ret,  BM_STATUS_DMA_RETRY))
             return;
     }
 
@@ -2942,7 +2957,7 @@ static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb)
     }
 }
 
-static void ide_dma_restart(IDEState *s)
+static void ide_dma_restart(IDEState *s, int is_read)
 {
     BMDMAState *bm = s->bmdma;
     ide_set_sector(s, bm->sector_num);
@@ -2950,7 +2965,13 @@ static void ide_dma_restart(IDEState *s)
     s->io_buffer_size = 0;
     s->nsector = bm->nsector;
     bm->cur_addr = bm->addr;
-    bm->dma_cb = ide_write_dma_cb;
+
+    if (is_read) {
+        bm->dma_cb = ide_read_dma_cb;
+    } else {
+        bm->dma_cb = ide_write_dma_cb;
+    }
+
     ide_dma_start(s, bm->dma_cb);
 }
 
-- 
1.6.3.rc4.29.g8146