qemu-block
[Top][All Lists]
Advanced

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

[Qemu-block] [PATCH] blockjob: fix user pause in block_job_error_action


From: Vladimir Sementsov-Ogievskiy
Subject: [Qemu-block] [PATCH] blockjob: fix user pause in block_job_error_action
Date: Tue, 19 Mar 2019 12:24:42 +0300

Job (especially mirror) may call block_job_error_action several
times before actual pause if it has several in-flight requests.

block_job_error_action will call job_pause more than once in this case,
which lead to following block-job-resume qmp command can't actually
resume the job.

Fix it by do not increase pause level in block_job_error_action if
user_paused already set.

Signed-off-by: Vladimir Sementsov-Ogievskiy <address@hidden>
---

Hi all!

I have a reproducer, however, I don't know how to make a test from it,
as I don't know a way to create a size-limited directory without root
access.

So here is it:

    #!/usr/bin/bash

    set -e

    MNT=/mirror-test
    A=$MNT/a
    B=$MNT/b
    STONE=$MNT/stone

    mkdir $MNT
    mount -t tmpfs -o size=11M tmpfs $MNT
    dd if=/dev/urandom of=$A bs=1M count=5
    dd if=/dev/urandom of=$STONE bs=1M count=5

    (
    cat <<QMP
    {"execute": "qmp_capabilities"} 
    {"execute": "drive-mirror", "arguments": {"device": "drive0", "sync": 
"full", "target": "$B", "on-target-error": "enospc"}} 
    QMP

    sleep 2
    rm -rf $STONE

    cat <<QMP
    {"execute": "query-block-jobs"} 
    {"execute": "block-job-resume", "arguments": {"device": "drive0"}} 
    QMP

    sleep 2
    cat <<QMP
    {"execute": "query-block-jobs"} 
    {"execute": "quit"} 
    QMP
    ) | ./x86_64-softmmu/qemu-system-x86_64 -nographic -qmp stdio -nodefaults 
-serial none -drive file=$A,id=drive0

    umount $MNT
    rmdir $MNT


 blockjob.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/blockjob.c b/blockjob.c
index 58de8cb024..730101d282 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -501,9 +501,11 @@ BlockErrorAction block_job_error_action(BlockJob *job, 
BlockdevOnError on_err,
                                         action);
     }
     if (action == BLOCK_ERROR_ACTION_STOP) {
-        job_pause(&job->job);
-        /* make the pause user visible, which will be resumed from QMP. */
-        job->job.user_paused = true;
+        if (!job->job.user_paused) {
+            job_pause(&job->job);
+            /* make the pause user visible, which will be resumed from QMP. */
+            job->job.user_paused = true;
+        }
         block_job_iostatus_set_err(job, error);
     }
     return action;
-- 
2.18.0




reply via email to

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