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