]> git.proxmox.com Git - mirror_qemu.git/blame - blockjob.c
blockjobs: add CONCLUDED state
[mirror_qemu.git] / blockjob.c
CommitLineData
2f0c9fe6
PB
1/*
2 * QEMU System Emulator block driver
3 *
4 * Copyright (c) 2011 IBM Corp.
5 * Copyright (c) 2012 Red Hat, Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
d38ea87a 26#include "qemu/osdep.h"
2f0c9fe6 27#include "qemu-common.h"
737e150e 28#include "block/block.h"
c87621ea 29#include "block/blockjob_int.h"
737e150e 30#include "block/block_int.h"
c9de4050 31#include "block/trace.h"
373340b2 32#include "sysemu/block-backend.h"
e688df6b 33#include "qapi/error.h"
9af23989 34#include "qapi/qapi-events-block-core.h"
cc7a8ea7 35#include "qapi/qmp/qerror.h"
10817bf0 36#include "qemu/coroutine.h"
7f0317cf 37#include "qemu/id.h"
1de7afc9 38#include "qemu/timer.h"
2f0c9fe6 39
fc24908e
PB
40/* Right now, this mutex is only needed to synchronize accesses to job->busy
41 * and job->sleep_timer, such as concurrent calls to block_job_do_yield and
42 * block_job_enter. */
43static QemuMutex block_job_mutex;
44
c9de4050
JS
45/* BlockJob State Transition Table */
46bool BlockJobSTT[BLOCK_JOB_STATUS__MAX][BLOCK_JOB_STATUS__MAX] = {
e0cf0364
JS
47 /* U, C, R, P, Y, S, X, E */
48 /* U: */ [BLOCK_JOB_STATUS_UNDEFINED] = {0, 1, 0, 0, 0, 0, 0, 0},
49 /* C: */ [BLOCK_JOB_STATUS_CREATED] = {0, 0, 1, 0, 0, 0, 1, 0},
50 /* R: */ [BLOCK_JOB_STATUS_RUNNING] = {0, 0, 0, 1, 1, 0, 1, 1},
51 /* P: */ [BLOCK_JOB_STATUS_PAUSED] = {0, 0, 1, 0, 0, 0, 0, 0},
52 /* Y: */ [BLOCK_JOB_STATUS_READY] = {0, 0, 0, 0, 0, 1, 1, 1},
53 /* S: */ [BLOCK_JOB_STATUS_STANDBY] = {0, 0, 0, 0, 1, 0, 0, 0},
54 /* X: */ [BLOCK_JOB_STATUS_ABORTING] = {0, 0, 0, 0, 0, 0, 0, 1},
55 /* E: */ [BLOCK_JOB_STATUS_CONCLUDED] = {0, 0, 0, 0, 0, 0, 0, 0},
c9de4050
JS
56};
57
0ec4dfb8 58bool BlockJobVerbTable[BLOCK_JOB_VERB__MAX][BLOCK_JOB_STATUS__MAX] = {
e0cf0364
JS
59 /* U, C, R, P, Y, S, X, E */
60 [BLOCK_JOB_VERB_CANCEL] = {0, 1, 1, 1, 1, 1, 0, 0},
61 [BLOCK_JOB_VERB_PAUSE] = {0, 1, 1, 1, 1, 1, 0, 0},
62 [BLOCK_JOB_VERB_RESUME] = {0, 1, 1, 1, 1, 1, 0, 0},
63 [BLOCK_JOB_VERB_SET_SPEED] = {0, 1, 1, 1, 1, 1, 0, 0},
64 [BLOCK_JOB_VERB_COMPLETE] = {0, 0, 0, 0, 1, 0, 0, 0},
0ec4dfb8
JS
65};
66
c9de4050
JS
67static void block_job_state_transition(BlockJob *job, BlockJobStatus s1)
68{
69 BlockJobStatus s0 = job->status;
70 assert(s1 >= 0 && s1 <= BLOCK_JOB_STATUS__MAX);
71 trace_block_job_state_transition(job, job->ret, BlockJobSTT[s0][s1] ?
72 "allowed" : "disallowed",
73 qapi_enum_lookup(&BlockJobStatus_lookup,
74 s0),
75 qapi_enum_lookup(&BlockJobStatus_lookup,
76 s1));
77 assert(BlockJobSTT[s0][s1]);
78 job->status = s1;
79}
80
0ec4dfb8
JS
81static int block_job_apply_verb(BlockJob *job, BlockJobVerb bv, Error **errp)
82{
83 assert(bv >= 0 && bv <= BLOCK_JOB_VERB__MAX);
84 trace_block_job_apply_verb(job, qapi_enum_lookup(&BlockJobStatus_lookup,
85 job->status),
86 qapi_enum_lookup(&BlockJobVerb_lookup, bv),
87 BlockJobVerbTable[bv][job->status] ?
88 "allowed" : "prohibited");
89 if (BlockJobVerbTable[bv][job->status]) {
90 return 0;
91 }
92 error_setg(errp, "Job '%s' in state '%s' cannot accept command verb '%s'",
93 job->id, qapi_enum_lookup(&BlockJobStatus_lookup, job->status),
94 qapi_enum_lookup(&BlockJobVerb_lookup, bv));
95 return -EPERM;
96}
97
fc24908e
PB
98static void block_job_lock(void)
99{
100 qemu_mutex_lock(&block_job_mutex);
101}
102
103static void block_job_unlock(void)
104{
105 qemu_mutex_unlock(&block_job_mutex);
106}
107
108static void __attribute__((__constructor__)) block_job_init(void)
109{
110 qemu_mutex_init(&block_job_mutex);
111}
112
8254b6d9
JS
113static void block_job_event_cancelled(BlockJob *job);
114static void block_job_event_completed(BlockJob *job, const char *msg);
aa9ef2e6 115static void block_job_enter_cond(BlockJob *job, bool(*fn)(BlockJob *job));
8254b6d9 116
c55a832f
FZ
117/* Transactional group of block jobs */
118struct BlockJobTxn {
119
120 /* Is this txn being cancelled? */
121 bool aborting;
122
123 /* List of jobs */
124 QLIST_HEAD(, BlockJob) jobs;
125
126 /* Reference count */
127 int refcnt;
128};
129
a7112795
AG
130static QLIST_HEAD(, BlockJob) block_jobs = QLIST_HEAD_INITIALIZER(block_jobs);
131
88691b37
PB
132/*
133 * The block job API is composed of two categories of functions.
134 *
135 * The first includes functions used by the monitor. The monitor is
136 * peculiar in that it accesses the block job list with block_job_get, and
137 * therefore needs consistency across block_job_get and the actual operation
138 * (e.g. block_job_set_speed). The consistency is achieved with
139 * aio_context_acquire/release. These functions are declared in blockjob.h.
140 *
141 * The second includes functions used by the block job drivers and sometimes
142 * by the core block layer. These do not care about locking, because the
143 * whole coroutine runs under the AioContext lock, and are declared in
144 * blockjob_int.h.
145 */
146
a7112795
AG
147BlockJob *block_job_next(BlockJob *job)
148{
149 if (!job) {
150 return QLIST_FIRST(&block_jobs);
151 }
152 return QLIST_NEXT(job, job_list);
153}
154
ffb1f10c
AG
155BlockJob *block_job_get(const char *id)
156{
157 BlockJob *job;
158
159 QLIST_FOREACH(job, &block_jobs, job_list) {
559b935f 160 if (job->id && !strcmp(id, job->id)) {
ffb1f10c
AG
161 return job;
162 }
163 }
164
165 return NULL;
166}
167
c8ab5c2d
PB
168BlockJobTxn *block_job_txn_new(void)
169{
170 BlockJobTxn *txn = g_new0(BlockJobTxn, 1);
171 QLIST_INIT(&txn->jobs);
172 txn->refcnt = 1;
173 return txn;
174}
175
176static void block_job_txn_ref(BlockJobTxn *txn)
177{
178 txn->refcnt++;
179}
180
181void block_job_txn_unref(BlockJobTxn *txn)
182{
183 if (txn && --txn->refcnt == 0) {
184 g_free(txn);
185 }
186}
187
188void block_job_txn_add_job(BlockJobTxn *txn, BlockJob *job)
189{
190 if (!txn) {
191 return;
192 }
193
194 assert(!job->txn);
195 job->txn = txn;
196
197 QLIST_INSERT_HEAD(&txn->jobs, job, txn_list);
198 block_job_txn_ref(txn);
199}
200
f321dcb5
PB
201static void block_job_pause(BlockJob *job)
202{
203 job->pause_count++;
204}
205
206static void block_job_resume(BlockJob *job)
207{
208 assert(job->pause_count > 0);
209 job->pause_count--;
210 if (job->pause_count) {
211 return;
212 }
213 block_job_enter(job);
214}
215
4172a003 216void block_job_ref(BlockJob *job)
05b0d8e3
PB
217{
218 ++job->refcnt;
219}
220
221static void block_job_attached_aio_context(AioContext *new_context,
222 void *opaque);
223static void block_job_detach_aio_context(void *opaque);
224
4172a003 225void block_job_unref(BlockJob *job)
05b0d8e3
PB
226{
227 if (--job->refcnt == 0) {
228 BlockDriverState *bs = blk_bs(job->blk);
0a3e155f 229 QLIST_REMOVE(job, job_list);
05b0d8e3
PB
230 bs->job = NULL;
231 block_job_remove_all_bdrv(job);
232 blk_remove_aio_context_notifier(job->blk,
233 block_job_attached_aio_context,
234 block_job_detach_aio_context, job);
235 blk_unref(job->blk);
236 error_free(job->blocker);
237 g_free(job->id);
fc24908e 238 assert(!timer_pending(&job->sleep_timer));
05b0d8e3
PB
239 g_free(job);
240 }
241}
242
463e0be1
SH
243static void block_job_attached_aio_context(AioContext *new_context,
244 void *opaque)
245{
246 BlockJob *job = opaque;
247
248 if (job->driver->attached_aio_context) {
249 job->driver->attached_aio_context(job, new_context);
250 }
251
252 block_job_resume(job);
253}
254
bae8196d
PB
255static void block_job_drain(BlockJob *job)
256{
257 /* If job is !job->busy this kicks it into the next pause point. */
258 block_job_enter(job);
259
260 blk_drain(job->blk);
261 if (job->driver->drain) {
262 job->driver->drain(job);
263 }
264}
265
463e0be1
SH
266static void block_job_detach_aio_context(void *opaque)
267{
268 BlockJob *job = opaque;
269
270 /* In case the job terminates during aio_poll()... */
271 block_job_ref(job);
272
273 block_job_pause(job);
274
463e0be1 275 while (!job->paused && !job->completed) {
bae8196d 276 block_job_drain(job);
463e0be1
SH
277 }
278
279 block_job_unref(job);
280}
281
f321dcb5
PB
282static char *child_job_get_parent_desc(BdrvChild *c)
283{
284 BlockJob *job = c->opaque;
285 return g_strdup_printf("%s job '%s'",
977c736f 286 BlockJobType_str(job->driver->job_type),
f321dcb5
PB
287 job->id);
288}
289
ad90feba 290static void child_job_drained_begin(BdrvChild *c)
f321dcb5 291{
ad90feba 292 BlockJob *job = c->opaque;
f321dcb5
PB
293 block_job_pause(job);
294}
295
ad90feba 296static void child_job_drained_end(BdrvChild *c)
f321dcb5 297{
ad90feba 298 BlockJob *job = c->opaque;
f321dcb5
PB
299 block_job_resume(job);
300}
301
ad90feba
KW
302static const BdrvChildRole child_job = {
303 .get_parent_desc = child_job_get_parent_desc,
304 .drained_begin = child_job_drained_begin,
305 .drained_end = child_job_drained_end,
306 .stay_at_node = true,
f321dcb5
PB
307};
308
bbc02b90
KW
309void block_job_remove_all_bdrv(BlockJob *job)
310{
311 GSList *l;
312 for (l = job->nodes; l; l = l->next) {
313 BdrvChild *c = l->data;
314 bdrv_op_unblock_all(c->bs, job->blocker);
315 bdrv_root_unref_child(c);
316 }
317 g_slist_free(job->nodes);
318 job->nodes = NULL;
319}
320
76d554e2
KW
321int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
322 uint64_t perm, uint64_t shared_perm, Error **errp)
23d402d4 323{
76d554e2
KW
324 BdrvChild *c;
325
326 c = bdrv_root_attach_child(bs, name, &child_job, perm, shared_perm,
327 job, errp);
328 if (c == NULL) {
329 return -EPERM;
330 }
331
332 job->nodes = g_slist_prepend(job->nodes, c);
23d402d4
AG
333 bdrv_ref(bs);
334 bdrv_op_block_all(bs, job->blocker);
76d554e2
KW
335
336 return 0;
23d402d4
AG
337}
338
559b935f
JS
339bool block_job_is_internal(BlockJob *job)
340{
341 return (job->id == NULL);
342}
343
5ccac6f1
JS
344static bool block_job_started(BlockJob *job)
345{
346 return job->co;
347}
348
e3796a24
JS
349/**
350 * All jobs must allow a pause point before entering their job proper. This
351 * ensures that jobs can be paused prior to being started, then resumed later.
352 */
353static void coroutine_fn block_job_co_entry(void *opaque)
354{
355 BlockJob *job = opaque;
356
357 assert(job && job->driver && job->driver->start);
358 block_job_pause_point(job);
359 job->driver->start(job);
360}
361
fc24908e
PB
362static void block_job_sleep_timer_cb(void *opaque)
363{
364 BlockJob *job = opaque;
365
366 block_job_enter(job);
367}
368
5ccac6f1
JS
369void block_job_start(BlockJob *job)
370{
371 assert(job && !block_job_started(job) && job->paused &&
e3796a24
JS
372 job->driver && job->driver->start);
373 job->co = qemu_coroutine_create(block_job_co_entry, job);
374 job->pause_count--;
375 job->busy = true;
376 job->paused = false;
c9de4050 377 block_job_state_transition(job, BLOCK_JOB_STATUS_RUNNING);
aef4278c 378 bdrv_coroutine_enter(blk_bs(job->blk), job->co);
5ccac6f1
JS
379}
380
e0cf0364
JS
381static void block_job_conclude(BlockJob *job)
382{
383 block_job_state_transition(job, BLOCK_JOB_STATUS_CONCLUDED);
384}
385
c55a832f
FZ
386static void block_job_completed_single(BlockJob *job)
387{
4fb588e9
PB
388 assert(job->completed);
389
10a3fbb0
JS
390 if (job->ret || block_job_is_cancelled(job)) {
391 block_job_state_transition(job, BLOCK_JOB_STATUS_ABORTING);
392 }
393
c55a832f
FZ
394 if (!job->ret) {
395 if (job->driver->commit) {
396 job->driver->commit(job);
397 }
398 } else {
399 if (job->driver->abort) {
400 job->driver->abort(job);
401 }
402 }
e8a40bf7
JS
403 if (job->driver->clean) {
404 job->driver->clean(job);
405 }
8254b6d9
JS
406
407 if (job->cb) {
408 job->cb(job->opaque, job->ret);
409 }
5ccac6f1
JS
410
411 /* Emit events only if we actually started */
412 if (block_job_started(job)) {
413 if (block_job_is_cancelled(job)) {
414 block_job_event_cancelled(job);
415 } else {
416 const char *msg = NULL;
417 if (job->ret < 0) {
418 msg = strerror(-job->ret);
419 }
420 block_job_event_completed(job, msg);
8254b6d9 421 }
8254b6d9
JS
422 }
423
75859b94
JS
424 QLIST_REMOVE(job, txn_list);
425 block_job_txn_unref(job->txn);
e0cf0364 426 block_job_conclude(job);
c55a832f
FZ
427 block_job_unref(job);
428}
429
4c241cf5
PB
430static void block_job_cancel_async(BlockJob *job)
431{
432 if (job->iostatus != BLOCK_DEVICE_IO_STATUS_OK) {
433 block_job_iostatus_reset(job);
434 }
435 if (job->user_paused) {
436 /* Do not call block_job_enter here, the caller will handle it. */
437 job->user_paused = false;
438 job->pause_count--;
439 }
440 job->cancelled = true;
441}
442
c8ab5c2d
PB
443static int block_job_finish_sync(BlockJob *job,
444 void (*finish)(BlockJob *, Error **errp),
445 Error **errp)
446{
447 Error *local_err = NULL;
448 int ret;
449
450 assert(blk_bs(job->blk)->job == job);
451
452 block_job_ref(job);
453
4fb588e9
PB
454 if (finish) {
455 finish(job, &local_err);
456 }
c8ab5c2d
PB
457 if (local_err) {
458 error_propagate(errp, local_err);
459 block_job_unref(job);
460 return -EBUSY;
461 }
462 /* block_job_drain calls block_job_enter, and it should be enough to
463 * induce progress until the job completes or moves to the main thread.
464 */
465 while (!job->deferred_to_main_loop && !job->completed) {
466 block_job_drain(job);
467 }
468 while (!job->completed) {
469 aio_poll(qemu_get_aio_context(), true);
470 }
471 ret = (job->cancelled && job->ret == 0) ? -ECANCELED : job->ret;
472 block_job_unref(job);
473 return ret;
474}
475
c55a832f
FZ
476static void block_job_completed_txn_abort(BlockJob *job)
477{
478 AioContext *ctx;
479 BlockJobTxn *txn = job->txn;
4fb588e9 480 BlockJob *other_job;
c55a832f
FZ
481
482 if (txn->aborting) {
483 /*
484 * We are cancelled by another job, which will handle everything.
485 */
486 return;
487 }
488 txn->aborting = true;
4fb588e9
PB
489 block_job_txn_ref(txn);
490
c55a832f
FZ
491 /* We are the first failed job. Cancel other jobs. */
492 QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
b6d2e599 493 ctx = blk_get_aio_context(other_job->blk);
c55a832f
FZ
494 aio_context_acquire(ctx);
495 }
4fb588e9
PB
496
497 /* Other jobs are effectively cancelled by us, set the status for
498 * them; this job, however, may or may not be cancelled, depending
499 * on the caller, so leave it. */
c55a832f 500 QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
4fb588e9
PB
501 if (other_job != job) {
502 block_job_cancel_async(other_job);
c55a832f 503 }
c55a832f 504 }
4fb588e9
PB
505 while (!QLIST_EMPTY(&txn->jobs)) {
506 other_job = QLIST_FIRST(&txn->jobs);
b6d2e599 507 ctx = blk_get_aio_context(other_job->blk);
4fb588e9
PB
508 if (!other_job->completed) {
509 assert(other_job->cancelled);
510 block_job_finish_sync(other_job, NULL, NULL);
511 }
c55a832f
FZ
512 block_job_completed_single(other_job);
513 aio_context_release(ctx);
514 }
4fb588e9
PB
515
516 block_job_txn_unref(txn);
c55a832f
FZ
517}
518
519static void block_job_completed_txn_success(BlockJob *job)
520{
521 AioContext *ctx;
522 BlockJobTxn *txn = job->txn;
523 BlockJob *other_job, *next;
524 /*
525 * Successful completion, see if there are other running jobs in this
526 * txn.
527 */
528 QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
529 if (!other_job->completed) {
530 return;
531 }
532 }
533 /* We are the last completed job, commit the transaction. */
534 QLIST_FOREACH_SAFE(other_job, &txn->jobs, txn_list, next) {
b6d2e599 535 ctx = blk_get_aio_context(other_job->blk);
c55a832f
FZ
536 aio_context_acquire(ctx);
537 assert(other_job->ret == 0);
538 block_job_completed_single(other_job);
539 aio_context_release(ctx);
540 }
541}
542
aa9ef2e6
JS
543/* Assumes the block_job_mutex is held */
544static bool block_job_timer_pending(BlockJob *job)
545{
546 return timer_pending(&job->sleep_timer);
547}
548
2f0c9fe6
PB
549void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
550{
551 Error *local_err = NULL;
aa9ef2e6 552 int64_t old_speed = job->speed;
2f0c9fe6 553
3fc4b10a 554 if (!job->driver->set_speed) {
c6bd8c70 555 error_setg(errp, QERR_UNSUPPORTED);
2f0c9fe6
PB
556 return;
557 }
0ec4dfb8
JS
558 if (block_job_apply_verb(job, BLOCK_JOB_VERB_SET_SPEED, errp)) {
559 return;
560 }
3fc4b10a 561 job->driver->set_speed(job, speed, &local_err);
84d18f06 562 if (local_err) {
2f0c9fe6
PB
563 error_propagate(errp, local_err);
564 return;
565 }
566
567 job->speed = speed;
d4fce188 568 if (speed && speed <= old_speed) {
aa9ef2e6
JS
569 return;
570 }
571
572 /* kick only if a timer is pending */
573 block_job_enter_cond(job, block_job_timer_pending);
2f0c9fe6
PB
574}
575
aeae883b
PB
576void block_job_complete(BlockJob *job, Error **errp)
577{
559b935f
JS
578 /* Should not be reachable via external interface for internal jobs */
579 assert(job->id);
0ec4dfb8
JS
580 if (block_job_apply_verb(job, BLOCK_JOB_VERB_COMPLETE, errp)) {
581 return;
582 }
583 if (job->pause_count || job->cancelled || !job->driver->complete) {
9df229c3
AG
584 error_setg(errp, "The active block job '%s' cannot be completed",
585 job->id);
aeae883b
PB
586 return;
587 }
588
3fc4b10a 589 job->driver->complete(job, errp);
aeae883b
PB
590}
591
0ec4dfb8 592void block_job_user_pause(BlockJob *job, Error **errp)
0df4ba58 593{
0ec4dfb8
JS
594 if (block_job_apply_verb(job, BLOCK_JOB_VERB_PAUSE, errp)) {
595 return;
596 }
597 if (job->user_paused) {
598 error_setg(errp, "Job is already paused");
599 return;
600 }
0df4ba58
JS
601 job->user_paused = true;
602 block_job_pause(job);
603}
604
0df4ba58
JS
605bool block_job_user_paused(BlockJob *job)
606{
6573d9c6 607 return job->user_paused;
0df4ba58
JS
608}
609
0ec4dfb8 610void block_job_user_resume(BlockJob *job, Error **errp)
0df4ba58 611{
0ec4dfb8
JS
612 assert(job);
613 if (!job->user_paused || job->pause_count <= 0) {
614 error_setg(errp, "Can't resume a job that was not paused");
615 return;
0df4ba58 616 }
0ec4dfb8
JS
617 if (block_job_apply_verb(job, BLOCK_JOB_VERB_RESUME, errp)) {
618 return;
619 }
620 block_job_iostatus_reset(job);
621 job->user_paused = false;
622 block_job_resume(job);
0df4ba58
JS
623}
624
8acc72a4
PB
625void block_job_cancel(BlockJob *job)
626{
e0cf0364
JS
627 if (job->status == BLOCK_JOB_STATUS_CONCLUDED) {
628 return;
629 } else if (block_job_started(job)) {
4c241cf5 630 block_job_cancel_async(job);
5ccac6f1
JS
631 block_job_enter(job);
632 } else {
633 block_job_completed(job, -ECANCELED);
634 }
8acc72a4
PB
635}
636
0ec4dfb8
JS
637void block_job_user_cancel(BlockJob *job, Error **errp)
638{
639 if (block_job_apply_verb(job, BLOCK_JOB_VERB_CANCEL, errp)) {
640 return;
641 }
642 block_job_cancel(job);
643}
644
345f9e1b
HR
645/* A wrapper around block_job_cancel() taking an Error ** parameter so it may be
646 * used with block_job_finish_sync() without the need for (rather nasty)
647 * function pointer casts there. */
648static void block_job_cancel_err(BlockJob *job, Error **errp)
649{
650 block_job_cancel(job);
651}
652
653int block_job_cancel_sync(BlockJob *job)
654{
655 return block_job_finish_sync(job, &block_job_cancel_err, NULL);
656}
657
a1a2af07
KW
658void block_job_cancel_sync_all(void)
659{
660 BlockJob *job;
661 AioContext *aio_context;
662
663 while ((job = QLIST_FIRST(&block_jobs))) {
b6d2e599 664 aio_context = blk_get_aio_context(job->blk);
a1a2af07
KW
665 aio_context_acquire(aio_context);
666 block_job_cancel_sync(job);
667 aio_context_release(aio_context);
668 }
669}
670
345f9e1b
HR
671int block_job_complete_sync(BlockJob *job, Error **errp)
672{
673 return block_job_finish_sync(job, &block_job_complete, errp);
674}
675
559b935f 676BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
30e628b7 677{
559b935f
JS
678 BlockJobInfo *info;
679
680 if (block_job_is_internal(job)) {
681 error_setg(errp, "Cannot query QEMU internal jobs");
682 return NULL;
683 }
684 info = g_new0(BlockJobInfo, 1);
977c736f 685 info->type = g_strdup(BlockJobType_str(job->driver->job_type));
8ccb9569 686 info->device = g_strdup(job->id);
32c81a4a 687 info->len = job->len;
fc24908e 688 info->busy = atomic_read(&job->busy);
751ebd76 689 info->paused = job->pause_count > 0;
32c81a4a
PB
690 info->offset = job->offset;
691 info->speed = job->speed;
692 info->io_status = job->iostatus;
ef6dbf1e 693 info->ready = job->ready;
58b295ba 694 info->status = job->status;
30e628b7
PB
695 return info;
696}
32c81a4a
PB
697
698static void block_job_iostatus_set_err(BlockJob *job, int error)
699{
700 if (job->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
701 job->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
702 BLOCK_DEVICE_IO_STATUS_FAILED;
703 }
704}
705
8254b6d9 706static void block_job_event_cancelled(BlockJob *job)
bcada37b 707{
559b935f
JS
708 if (block_job_is_internal(job)) {
709 return;
710 }
711
bcada37b 712 qapi_event_send_block_job_cancelled(job->driver->job_type,
8ccb9569 713 job->id,
bcada37b
WX
714 job->len,
715 job->offset,
716 job->speed,
717 &error_abort);
718}
32c81a4a 719
8254b6d9 720static void block_job_event_completed(BlockJob *job, const char *msg)
a66a2a36 721{
559b935f
JS
722 if (block_job_is_internal(job)) {
723 return;
724 }
725
bcada37b 726 qapi_event_send_block_job_completed(job->driver->job_type,
8ccb9569 727 job->id,
bcada37b
WX
728 job->len,
729 job->offset,
730 job->speed,
731 !!msg,
732 msg,
733 &error_abort);
a66a2a36
PB
734}
735
88691b37
PB
736/*
737 * API for block job drivers and the block layer. These functions are
738 * declared in blockjob_int.h.
739 */
740
741void *block_job_create(const char *job_id, const BlockJobDriver *driver,
75859b94 742 BlockJobTxn *txn, BlockDriverState *bs, uint64_t perm,
88691b37
PB
743 uint64_t shared_perm, int64_t speed, int flags,
744 BlockCompletionFunc *cb, void *opaque, Error **errp)
745{
746 BlockBackend *blk;
747 BlockJob *job;
748 int ret;
749
750 if (bs->job) {
751 error_setg(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(bs));
752 return NULL;
753 }
754
755 if (job_id == NULL && !(flags & BLOCK_JOB_INTERNAL)) {
756 job_id = bdrv_get_device_name(bs);
757 if (!*job_id) {
758 error_setg(errp, "An explicit job ID is required for this node");
759 return NULL;
760 }
761 }
762
763 if (job_id) {
764 if (flags & BLOCK_JOB_INTERNAL) {
765 error_setg(errp, "Cannot specify job ID for internal block job");
766 return NULL;
767 }
768
769 if (!id_wellformed(job_id)) {
770 error_setg(errp, "Invalid job ID '%s'", job_id);
771 return NULL;
772 }
773
774 if (block_job_get(job_id)) {
775 error_setg(errp, "Job ID '%s' already in use", job_id);
776 return NULL;
777 }
778 }
779
780 blk = blk_new(perm, shared_perm);
781 ret = blk_insert_bs(blk, bs, errp);
782 if (ret < 0) {
783 blk_unref(blk);
784 return NULL;
785 }
786
787 job = g_malloc0(driver->instance_size);
788 job->driver = driver;
789 job->id = g_strdup(job_id);
790 job->blk = blk;
791 job->cb = cb;
792 job->opaque = opaque;
793 job->busy = false;
794 job->paused = true;
795 job->pause_count = 1;
796 job->refcnt = 1;
c9de4050 797 block_job_state_transition(job, BLOCK_JOB_STATUS_CREATED);
fc24908e
PB
798 aio_timer_init(qemu_get_aio_context(), &job->sleep_timer,
799 QEMU_CLOCK_REALTIME, SCALE_NS,
800 block_job_sleep_timer_cb, job);
88691b37
PB
801
802 error_setg(&job->blocker, "block device is in use by block job: %s",
977c736f 803 BlockJobType_str(driver->job_type));
88691b37
PB
804 block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort);
805 bs->job = job;
806
88691b37
PB
807 bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
808
809 QLIST_INSERT_HEAD(&block_jobs, job, job_list);
810
811 blk_add_aio_context_notifier(blk, block_job_attached_aio_context,
812 block_job_detach_aio_context, job);
813
814 /* Only set speed when necessary to avoid NotSupported error */
815 if (speed != 0) {
816 Error *local_err = NULL;
817
818 block_job_set_speed(job, speed, &local_err);
819 if (local_err) {
820 block_job_unref(job);
821 error_propagate(errp, local_err);
822 return NULL;
823 }
824 }
75859b94
JS
825
826 /* Single jobs are modeled as single-job transactions for sake of
827 * consolidating the job management logic */
828 if (!txn) {
829 txn = block_job_txn_new();
830 block_job_txn_add_job(txn, job);
831 block_job_txn_unref(txn);
832 } else {
833 block_job_txn_add_job(txn, job);
834 }
835
88691b37
PB
836 return job;
837}
838
f321dcb5
PB
839void block_job_pause_all(void)
840{
841 BlockJob *job = NULL;
842 while ((job = block_job_next(job))) {
843 AioContext *aio_context = blk_get_aio_context(job->blk);
844
845 aio_context_acquire(aio_context);
3d5d319e 846 block_job_ref(job);
f321dcb5
PB
847 block_job_pause(job);
848 aio_context_release(aio_context);
849 }
850}
851
88691b37
PB
852void block_job_early_fail(BlockJob *job)
853{
854 block_job_unref(job);
855}
856
857void block_job_completed(BlockJob *job, int ret)
858{
75859b94 859 assert(job && job->txn && !job->completed);
88691b37 860 assert(blk_bs(job->blk)->job == job);
88691b37
PB
861 job->completed = true;
862 job->ret = ret;
75859b94 863 if (ret < 0 || block_job_is_cancelled(job)) {
88691b37
PB
864 block_job_completed_txn_abort(job);
865 } else {
866 block_job_completed_txn_success(job);
867 }
868}
869
870static bool block_job_should_pause(BlockJob *job)
871{
872 return job->pause_count > 0;
873}
874
fc24908e
PB
875/* Yield, and schedule a timer to reenter the coroutine after @ns nanoseconds.
876 * Reentering the job coroutine with block_job_enter() before the timer has
877 * expired is allowed and cancels the timer.
878 *
879 * If @ns is (uint64_t) -1, no timer is scheduled and block_job_enter() must be
880 * called explicitly. */
881static void block_job_do_yield(BlockJob *job, uint64_t ns)
356f59b8 882{
fc24908e
PB
883 block_job_lock();
884 if (ns != -1) {
885 timer_mod(&job->sleep_timer, ns);
886 }
356f59b8 887 job->busy = false;
fc24908e 888 block_job_unlock();
356f59b8
PB
889 qemu_coroutine_yield();
890
891 /* Set by block_job_enter before re-entering the coroutine. */
892 assert(job->busy);
893}
894
88691b37
PB
895void coroutine_fn block_job_pause_point(BlockJob *job)
896{
897 assert(job && block_job_started(job));
898
899 if (!block_job_should_pause(job)) {
900 return;
901 }
902 if (block_job_is_cancelled(job)) {
903 return;
904 }
905
906 if (job->driver->pause) {
907 job->driver->pause(job);
908 }
909
910 if (block_job_should_pause(job) && !block_job_is_cancelled(job)) {
58b295ba 911 BlockJobStatus status = job->status;
c9de4050
JS
912 block_job_state_transition(job, status == BLOCK_JOB_STATUS_READY ? \
913 BLOCK_JOB_STATUS_STANDBY : \
914 BLOCK_JOB_STATUS_PAUSED);
88691b37 915 job->paused = true;
fc24908e 916 block_job_do_yield(job, -1);
88691b37 917 job->paused = false;
c9de4050 918 block_job_state_transition(job, status);
88691b37
PB
919 }
920
921 if (job->driver->resume) {
922 job->driver->resume(job);
923 }
924}
925
f321dcb5
PB
926void block_job_resume_all(void)
927{
3d5d319e
AG
928 BlockJob *job, *next;
929
930 QLIST_FOREACH_SAFE(job, &block_jobs, job_list, next) {
f321dcb5
PB
931 AioContext *aio_context = blk_get_aio_context(job->blk);
932
933 aio_context_acquire(aio_context);
934 block_job_resume(job);
3d5d319e 935 block_job_unref(job);
f321dcb5
PB
936 aio_context_release(aio_context);
937 }
938}
939
aa9ef2e6
JS
940/*
941 * Conditionally enter a block_job pending a call to fn() while
942 * under the block_job_lock critical section.
943 */
944static void block_job_enter_cond(BlockJob *job, bool(*fn)(BlockJob *job))
88691b37 945{
eb05e011
PB
946 if (!block_job_started(job)) {
947 return;
948 }
949 if (job->deferred_to_main_loop) {
950 return;
951 }
952
fc24908e 953 block_job_lock();
356f59b8 954 if (job->busy) {
fc24908e 955 block_job_unlock();
356f59b8 956 return;
88691b37 957 }
356f59b8 958
aa9ef2e6
JS
959 if (fn && !fn(job)) {
960 block_job_unlock();
961 return;
962 }
963
fc24908e
PB
964 assert(!job->deferred_to_main_loop);
965 timer_del(&job->sleep_timer);
356f59b8 966 job->busy = true;
fc24908e 967 block_job_unlock();
356f59b8 968 aio_co_wake(job->co);
88691b37
PB
969}
970
aa9ef2e6
JS
971void block_job_enter(BlockJob *job)
972{
973 block_job_enter_cond(job, NULL);
974}
975
88691b37
PB
976bool block_job_is_cancelled(BlockJob *job)
977{
978 return job->cancelled;
979}
980
5bf1d5a7 981void block_job_sleep_ns(BlockJob *job, int64_t ns)
88691b37
PB
982{
983 assert(job->busy);
984
985 /* Check cancellation *before* setting busy = false, too! */
986 if (block_job_is_cancelled(job)) {
987 return;
988 }
989
88691b37 990 if (!block_job_should_pause(job)) {
fc24908e 991 block_job_do_yield(job, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + ns);
88691b37 992 }
88691b37
PB
993
994 block_job_pause_point(job);
995}
996
997void block_job_yield(BlockJob *job)
998{
999 assert(job->busy);
1000
1001 /* Check cancellation *before* setting busy = false, too! */
1002 if (block_job_is_cancelled(job)) {
1003 return;
1004 }
1005
88691b37 1006 if (!block_job_should_pause(job)) {
fc24908e 1007 block_job_do_yield(job, -1);
88691b37 1008 }
88691b37
PB
1009
1010 block_job_pause_point(job);
1011}
1012
2caf63a9
PB
1013void block_job_iostatus_reset(BlockJob *job)
1014{
4c241cf5
PB
1015 if (job->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
1016 return;
1017 }
1018 assert(job->user_paused && job->pause_count > 0);
2caf63a9
PB
1019 job->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
1020}
1021
bcada37b 1022void block_job_event_ready(BlockJob *job)
a66a2a36 1023{
c9de4050 1024 block_job_state_transition(job, BLOCK_JOB_STATUS_READY);
ef6dbf1e
HR
1025 job->ready = true;
1026
559b935f
JS
1027 if (block_job_is_internal(job)) {
1028 return;
1029 }
1030
518848a2 1031 qapi_event_send_block_job_ready(job->driver->job_type,
8ccb9569 1032 job->id,
518848a2
MA
1033 job->len,
1034 job->offset,
1035 job->speed, &error_abort);
a66a2a36
PB
1036}
1037
81e254dc 1038BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
32c81a4a
PB
1039 int is_read, int error)
1040{
1041 BlockErrorAction action;
1042
1043 switch (on_err) {
1044 case BLOCKDEV_ON_ERROR_ENOSPC:
8c398252 1045 case BLOCKDEV_ON_ERROR_AUTO:
a589569f
WX
1046 action = (error == ENOSPC) ?
1047 BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
32c81a4a
PB
1048 break;
1049 case BLOCKDEV_ON_ERROR_STOP:
a589569f 1050 action = BLOCK_ERROR_ACTION_STOP;
32c81a4a
PB
1051 break;
1052 case BLOCKDEV_ON_ERROR_REPORT:
a589569f 1053 action = BLOCK_ERROR_ACTION_REPORT;
32c81a4a
PB
1054 break;
1055 case BLOCKDEV_ON_ERROR_IGNORE:
a589569f 1056 action = BLOCK_ERROR_ACTION_IGNORE;
32c81a4a
PB
1057 break;
1058 default:
1059 abort();
1060 }
559b935f
JS
1061 if (!block_job_is_internal(job)) {
1062 qapi_event_send_block_job_error(job->id,
1063 is_read ? IO_OPERATION_TYPE_READ :
1064 IO_OPERATION_TYPE_WRITE,
1065 action, &error_abort);
1066 }
a589569f 1067 if (action == BLOCK_ERROR_ACTION_STOP) {
0ec4dfb8 1068 block_job_pause(job);
751ebd76 1069 /* make the pause user visible, which will be resumed from QMP. */
0ec4dfb8 1070 job->user_paused = true;
32c81a4a 1071 block_job_iostatus_set_err(job, error);
32c81a4a
PB
1072 }
1073 return action;
1074}
dec7d421
SH
1075
1076typedef struct {
1077 BlockJob *job;
dec7d421
SH
1078 AioContext *aio_context;
1079 BlockJobDeferToMainLoopFn *fn;
1080 void *opaque;
1081} BlockJobDeferToMainLoopData;
1082
1083static void block_job_defer_to_main_loop_bh(void *opaque)
1084{
1085 BlockJobDeferToMainLoopData *data = opaque;
1086 AioContext *aio_context;
1087
dec7d421
SH
1088 /* Prevent race with block_job_defer_to_main_loop() */
1089 aio_context_acquire(data->aio_context);
1090
1091 /* Fetch BDS AioContext again, in case it has changed */
b6d2e599 1092 aio_context = blk_get_aio_context(data->job->blk);
d79df2a2
PB
1093 if (aio_context != data->aio_context) {
1094 aio_context_acquire(aio_context);
1095 }
dec7d421
SH
1096
1097 data->fn(data->job, data->opaque);
1098
d79df2a2
PB
1099 if (aio_context != data->aio_context) {
1100 aio_context_release(aio_context);
1101 }
dec7d421
SH
1102
1103 aio_context_release(data->aio_context);
1104
1105 g_free(data);
1106}
1107
1108void block_job_defer_to_main_loop(BlockJob *job,
1109 BlockJobDeferToMainLoopFn *fn,
1110 void *opaque)
1111{
1112 BlockJobDeferToMainLoopData *data = g_malloc(sizeof(*data));
1113 data->job = job;
b6d2e599 1114 data->aio_context = blk_get_aio_context(job->blk);
dec7d421
SH
1115 data->fn = fn;
1116 data->opaque = opaque;
794f0141 1117 job->deferred_to_main_loop = true;
dec7d421 1118
fffb6e12
PB
1119 aio_bh_schedule_oneshot(qemu_get_aio_context(),
1120 block_job_defer_to_main_loop_bh, data);
dec7d421 1121}