All of lore.kernel.org
 help / color / mirror / Atom feed
From: Max Reitz <mreitz@redhat.com>
To: Kevin Wolf <kwolf@redhat.com>
Cc: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
	John Snow <jsnow@redhat.com>,
	qemu-devel@nongnu.org, qemu-block@nongnu.org
Subject: Re: [PATCH for-6.1? v2 5/7] job: Add job_cancel_requested()
Date: Wed, 4 Aug 2021 10:07:15 +0200	[thread overview]
Message-ID: <13d07f4b-9659-4576-1757-a7d75f7e16c2@redhat.com> (raw)
In-Reply-To: <YQlRzOzXOxeBLb0B@redhat.com>

On 03.08.21 16:25, Kevin Wolf wrote:
> Am 26.07.2021 um 16:46 hat Max Reitz geschrieben:
>> Most callers of job_is_cancelled() actually want to know whether the job
>> is on its way to immediate termination.  For example, we refuse to pause
>> jobs that are cancelled; but this only makes sense for jobs that are
>> really actually cancelled.
>>
>> A mirror job that is cancelled during READY with force=false should
>> absolutely be allowed to pause.  This "cancellation" (which is actually
>> a kind of completion) may take an indefinite amount of time, and so
>> should behave like any job during normal operation.  For example, with
>> on-target-error=stop, the job should stop on write errors.  (In
>> contrast, force-cancelled jobs should not get write errors, as they
>> should just terminate and not do further I/O.)
>>
>> Therefore, redefine job_is_cancelled() to only return true for jobs that
>> are force-cancelled (which as of HEAD^ means any job that interprets the
>> cancellation request as a request for immediate termination), and add
>> job_cancel_request() as the general variant, which returns true for any
>> jobs which have been requested to be cancelled, whether it be
>> immediately or after an arbitrarily long completion phase.
>>
>> Buglink: https://gitlab.com/qemu-project/qemu/-/issues/462
>> Signed-off-by: Max Reitz <mreitz@redhat.com>
>> ---
>>   include/qemu/job.h |  8 +++++++-
>>   block/mirror.c     | 10 ++++------
>>   job.c              |  7 ++++++-
>>   3 files changed, 17 insertions(+), 8 deletions(-)
>>
>> diff --git a/include/qemu/job.h b/include/qemu/job.h
>> index 8aa90f7395..032edf3c5f 100644
>> --- a/include/qemu/job.h
>> +++ b/include/qemu/job.h
>> @@ -436,9 +436,15 @@ const char *job_type_str(const Job *job);
>>   /** Returns true if the job should not be visible to the management layer. */
>>   bool job_is_internal(Job *job);
>>   
>> -/** Returns whether the job is scheduled for cancellation. */
>> +/** Returns whether the job is being cancelled. */
>>   bool job_is_cancelled(Job *job);
>>   
>> +/**
>> + * Returns whether the job is scheduled for cancellation (at an
>> + * indefinite point).
>> + */
>> +bool job_cancel_requested(Job *job);
> I don't think non-force blockdev-cancel for mirror should actually be
> considered cancellation, so what is the question that this function
> answers?
>
> "Is this a cancelled job, or a mirror block job that is supposed to
> complete soon, but only if it doesn't switch over the users to the
> target on completion"?

Well, technically yes, but it was more intended as “Has the user ever 
invoked (block-)job-cancel on this job?”.

> Is this ever a reasonable question to ask, except maybe inside the
> mirror implementation itself?

I asked myself the same for v3, but found two places in job.c where I 
would like to keep it:

First, there’s an assertion in job_completed_txn_abort().  All jobs 
other than @job have been force-cancelled, and so job_is_cancelled() 
would be true for them.  As for @job itself, the function is mostly 
called when the job’s return value is not 0, but a soft-cancelled mirror 
does have a return value of 0 and so would not end up in that function.
But job_cancel() invokes job_completed_txn_abort() if the job has been 
deferred to the main loop, which mostly correlates with the job having 
been completed (in which case the assertion is skipped), but not 100 % 
(there’s a small window between setting deferred_to_main_loop and the 
job changing to a completed state).
So I’d prefer to keep the assertion as-is functionally, i.e. to only 
check job->cancelled.

Second, job_complete() refuses to let a job complete that has been 
cancelled.  This function is basically only invoked by the user (through 
qmp_block_job_complete()/qmp_job_complete(), or job_complete_sync(), 
which comes from qemu-img), so I believe that it should correspond to 
the external interface we have right now; i.e., if the user has invoked 
(block-)job-cancel at one point, job_complete() should generally return 
an error.

> job_complete() is the only function outside of mirror that seems to use
> it. But even there, it feels wrong to make a difference. Either we
> accept redundant completion requests, or we don't. It doesn't really
> matter how the job reconfigures the graph on completion. (Also, I feel
> this should really have been part of the state machine, but I'm not sure
> if we want to touch it now...)

Well, yes, I don’t think it makes a difference because I don’t think 
anyone will first tell the job via block-job-cancel to complete without 
pivoting, and then change their mind and call block-job-complete after 
all.  (Not least because that’s an error pre-series.)

Also, I’m not even sure whether completing after a soft cancel request 
works.  I don’t think any of our code accounts for such a case, so I’d 
rather avoid allowing it if there’s no need to allow it anyway.

Max



  reply	other threads:[~2021-08-04  8:08 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-26 14:46 [PATCH for-6.1? v2 0/7] mirror: Handle errors after READY cancel Max Reitz
2021-07-26 14:46 ` [PATCH for-6.1? v2 1/7] mirror: Keep s->synced on error Max Reitz
2021-07-26 14:46 ` [PATCH for-6.1? v2 2/7] mirror: Drop s->synced Max Reitz
2021-07-26 15:26   ` Eric Blake
2021-07-27 11:41   ` Vladimir Sementsov-Ogievskiy
2021-07-26 14:46 ` [PATCH for-6.1? v2 3/7] job: @force parameter for job_cancel_sync{, _all}() Max Reitz
2021-08-03 14:00   ` [PATCH for-6.1? v2 3/7] job: @force parameter for job_cancel_sync{,_all}() Kevin Wolf
2021-07-26 14:46 ` [PATCH for-6.1? v2 4/7] jobs: Give Job.force_cancel more meaning Max Reitz
2021-07-26 21:38   ` Eric Blake
2021-07-27 12:40   ` Vladimir Sementsov-Ogievskiy
2021-07-26 14:46 ` [PATCH for-6.1? v2 5/7] job: Add job_cancel_requested() Max Reitz
2021-07-27 13:04   ` Vladimir Sementsov-Ogievskiy
2021-07-27 15:39     ` Max Reitz
2021-07-27 15:47       ` Vladimir Sementsov-Ogievskiy
2021-08-02 10:23         ` Max Reitz
2021-08-03 12:35           ` Vladimir Sementsov-Ogievskiy
2021-08-03 14:25   ` Kevin Wolf
2021-08-04  8:07     ` Max Reitz [this message]
2021-08-04 10:34       ` Kevin Wolf
2021-08-04 11:00         ` Peter Krempa
2021-08-04 14:15         ` Max Reitz
2021-07-26 14:46 ` [PATCH for-6.1? v2 6/7] mirror: Check job_is_cancelled() earlier Max Reitz
2021-07-27 13:13   ` Vladimir Sementsov-Ogievskiy
2021-07-27 15:40     ` Max Reitz
2021-08-03 14:34   ` Kevin Wolf
2021-08-04  8:25     ` Max Reitz
2021-08-04  9:48       ` Kevin Wolf
2021-08-04 10:12         ` Max Reitz
2021-07-26 14:46 ` [PATCH for-6.1? v2 7/7] iotests: Add mirror-ready-cancel-error test Max Reitz
2021-07-27 13:24   ` Vladimir Sementsov-Ogievskiy
2021-08-03 14:36 ` [PATCH for-6.1? v2 0/7] mirror: Handle errors after READY cancel Kevin Wolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=13d07f4b-9659-4576-1757-a7d75f7e16c2@redhat.com \
    --to=mreitz@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.