qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] Re: -drive werror=stop can cause state change handlers run


From: Markus Armbruster
Subject: [Qemu-devel] Re: -drive werror=stop can cause state change handlers run out of order
Date: Mon, 27 Jul 2009 20:44:27 +0200
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.3 (gnu/linux)

I reproduced the problem as follows.

The appended patch does two things:

1. It lets me inject write errors by setting variable inject_write_error
   in gdb.  Crude, but works.

2. It shows what audio_vm_change_state_handler() does.

Apply it and start a guest with sound and werror=stop under gdb, say

    $ gdb --args qemu -drive file=f10.qcow2,werror=stop -soundhw ac97 -monitor 
unix:monitor,server,nowait

Let it boot to single user mode (just to speed things up).  When
everything's nicely quiet, do

    (gdb) set inject_write_error=1000
    (gdb) c

Trigger a write.  Running "sync" works for me.  Guest stops, printing

    injecting write error on ide0-hd0
    audio_vm_change_state_handler voice disable

Connect to the monitor and resume the guest ("c").  Guest stops,
printing

    injecting write error on ide0-hd0
    audio_vm_change_state_handler voice disable
    injecting write error on ide0-hd0
    audio_vm_change_state_handler voice enable

You see that audio_vm_change_state_handler() are run in the wrong order,
and voice is thus left enabled rather than disabled.



diff --git a/audio/audio.c b/audio/audio.c
index 694a83e..64d079f 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1630,6 +1630,9 @@ static void audio_vm_change_state_handler (void *opaque, 
int running,
     HWVoiceIn *hwi = NULL;
     int op = running ? VOICE_ENABLE : VOICE_DISABLE;
 
+    printf("audio_vm_change_state_handler voice %s\n",
+           running ? "enable" : "disable");
+
     s->vm_running = running;
     while ((hwo = audio_pcm_hw_find_any_enabled_out (hwo))) {
         hwo->pcm_ops->ctl_out (hwo, op);
diff --git a/hw/ide.c b/hw/ide.c
index 1e56786..98d0315 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -1060,6 +1061,8 @@ static void ide_sector_write_timer_cb(void *opaque)
     ide_set_irq(s);
 }
 
+int inject_write_error;
+
 static void ide_sector_write(IDEState *s)
 {
     int64_t sector_num;
@@ -1075,6 +1078,12 @@ static void ide_sector_write(IDEState *s)
         n = s->req_nb_sectors;
     ret = bdrv_write(s->bs, sector_num, s->io_buffer, n);
 
+    if (inject_write_error) {
+        printf("injecting write error on %s\n", s->bs->device_name);
+        ret = -EIO;
+        inject_write_error--;
+    }
+
     if (ret != 0) {
         if (ide_handle_write_error(s, -ret, BM_STATUS_PIO_RETRY))
             return;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]