Lines Matching +full:s +full:- +full:mode
12 * See the COPYING file in the top-level directory.
22 #include "system/block-backend.h"
36 ReplicationMode mode; member
50 static void replication_start(ReplicationState *rs, ReplicationMode mode,
57 #define REPLICATION_MODE "mode"
58 #define REPLICATION_TOP_ID "top-id"
86 BDRVReplicationState *s = bs->opaque; in replication_open() local
88 const char *mode; in replication_open() local
96 ret = -EINVAL; in replication_open()
102 mode = qemu_opt_get(opts, REPLICATION_MODE); in replication_open()
103 if (!mode) { in replication_open()
104 error_setg(errp, "Missing the option mode"); in replication_open()
108 if (!strcmp(mode, "primary")) { in replication_open()
109 s->mode = REPLICATION_MODE_PRIMARY; in replication_open()
113 "The primary side does not support option top-id"); in replication_open()
116 } else if (!strcmp(mode, "secondary")) { in replication_open()
117 s->mode = REPLICATION_MODE_SECONDARY; in replication_open()
119 s->top_id = g_strdup(top_id); in replication_open()
120 if (!s->top_id) { in replication_open()
121 error_setg(errp, "Missing the option top-id"); in replication_open()
126 "The option mode's value should be primary or secondary"); in replication_open()
130 s->rs = replication_new(bs, &replication_ops); in replication_open()
141 BDRVReplicationState *s = bs->opaque; in replication_close() local
145 if (s->stage == BLOCK_REPLICATION_RUNNING) { in replication_close()
146 replication_stop(s->rs, false, NULL); in replication_close()
148 if (s->stage == BLOCK_REPLICATION_FAILOVER) { in replication_close()
149 commit_job = &s->commit_job->job; in replication_close()
150 assert(commit_job->aio_context == qemu_get_current_aio_context()); in replication_close()
154 if (s->mode == REPLICATION_MODE_SECONDARY) { in replication_close()
155 g_free(s->top_id); in replication_close()
158 replication_remove(s->rs); in replication_close()
173 if ((bs->open_flags & (BDRV_O_INACTIVE | BDRV_O_RDWR)) == BDRV_O_RDWR) { in replication_child_perm()
185 return bdrv_co_getlength(bs->file->bs); in replication_co_getlength()
188 static int replication_get_io_status(BDRVReplicationState *s) in replication_get_io_status() argument
190 switch (s->stage) { in replication_get_io_status()
192 return -EIO; in replication_get_io_status()
196 return s->mode == REPLICATION_MODE_PRIMARY ? -EIO : 0; in replication_get_io_status()
198 return s->mode == REPLICATION_MODE_PRIMARY ? -EIO : 1; in replication_get_io_status()
202 * is swapped, so we can operate bs->file directly in replication_get_io_status()
204 return s->mode == REPLICATION_MODE_PRIMARY ? -EIO : 0; in replication_get_io_status()
210 static int replication_return_value(BDRVReplicationState *s, int ret) in replication_return_value() argument
212 if (s->mode == REPLICATION_MODE_SECONDARY) { in replication_return_value()
217 s->error = ret; in replication_return_value()
228 BDRVReplicationState *s = bs->opaque; in replication_co_readv() local
231 if (s->mode == REPLICATION_MODE_PRIMARY) { in replication_co_readv()
233 return -EIO; in replication_co_readv()
236 ret = replication_get_io_status(s); in replication_co_readv()
241 ret = bdrv_co_preadv(bs->file, sector_num * BDRV_SECTOR_SIZE, in replication_co_readv()
244 return replication_return_value(s, ret); in replication_co_readv()
251 BDRVReplicationState *s = bs->opaque; in replication_co_writev() local
254 BdrvChild *top = bs->file; in replication_co_writev()
255 BdrvChild *base = s->secondary_disk; in replication_co_writev()
260 ret = replication_get_io_status(s); in replication_co_writev()
268 return replication_return_value(s, ret); in replication_co_writev()
275 qemu_iovec_init(&hd_qiov, qiov->niov); in replication_co_writev()
279 ret = bdrv_co_is_allocated_above(top->bs, base->bs, false, in replication_co_writev()
299 remaining_sectors -= n; in replication_co_writev()
313 BDRVReplicationState *s = bs->opaque; in secondary_do_checkpoint() local
320 if (!s->backup_job) { in secondary_do_checkpoint()
325 backup_do_checkpoint(s->backup_job, &local_err); in secondary_do_checkpoint()
331 active_disk = bs->file; in secondary_do_checkpoint()
332 if (!active_disk->bs->drv) { in secondary_do_checkpoint()
333 error_setg(errp, "Active disk %s is ejected", in secondary_do_checkpoint()
334 active_disk->bs->node_name); in secondary_do_checkpoint()
343 if (!s->hidden_disk->bs->drv) { in secondary_do_checkpoint()
344 error_setg(errp, "Hidden disk %s is ejected", in secondary_do_checkpoint()
345 s->hidden_disk->bs->node_name); in secondary_do_checkpoint()
349 ret = bdrv_make_empty(s->hidden_disk, errp); in secondary_do_checkpoint()
357 * The first call puts s->hidden_disk and s->secondary_disk in
358 * r/w mode, and the second puts them back in their original state.
363 BDRVReplicationState *s = bs->opaque; in reopen_backing_file() local
371 * s->hidden_disk and s->secondary_disk may not be set yet, as they will in reopen_backing_file()
374 hidden_disk = bs->file->bs->backing; in reopen_backing_file()
375 secondary_disk = hidden_disk->bs->backing; in reopen_backing_file()
378 s->orig_hidden_read_only = bdrv_is_read_only(hidden_disk->bs); in reopen_backing_file()
379 s->orig_secondary_read_only = bdrv_is_read_only(secondary_disk->bs); in reopen_backing_file()
382 if (s->orig_hidden_read_only) { in reopen_backing_file()
385 reopen_queue = bdrv_reopen_queue(reopen_queue, hidden_disk->bs, in reopen_backing_file()
389 if (s->orig_secondary_read_only) { in reopen_backing_file()
392 reopen_queue = bdrv_reopen_queue(reopen_queue, secondary_disk->bs, in reopen_backing_file()
403 BDRVReplicationState *s = bs->opaque; in backup_job_cleanup() local
406 s->backup_job = NULL; in backup_job_cleanup()
408 top_bs = bdrv_lookup_bs(s->top_id, s->top_id, NULL); in backup_job_cleanup()
412 bdrv_op_unblock_all(top_bs, s->blocker); in backup_job_cleanup()
413 error_free(s->blocker); in backup_job_cleanup()
420 BDRVReplicationState *s = bs->opaque; in backup_job_completed() local
422 if (s->stage != BLOCK_REPLICATION_FAILOVER) { in backup_job_completed()
424 s->error = -EIO; in backup_job_completed()
440 /* Iterate over top_bs's children */ in check_top_bs()
441 QLIST_FOREACH(child, &top_bs->children, next) { in check_top_bs()
442 if (child->bs == bs || check_top_bs(child->bs, bs)) { in check_top_bs()
450 static void replication_start(ReplicationState *rs, ReplicationMode mode, in replication_start() argument
453 BlockDriverState *bs = rs->opaque; in replication_start()
454 BDRVReplicationState *s; in replication_start() local
463 s = bs->opaque; in replication_start()
465 if (s->stage == BLOCK_REPLICATION_DONE || in replication_start()
466 s->stage == BLOCK_REPLICATION_FAILOVER) { in replication_start()
475 if (s->stage != BLOCK_REPLICATION_NONE) { in replication_start()
480 if (s->mode != mode) { in replication_start()
481 error_setg(errp, "The parameter mode's value is invalid, needs %d," in replication_start()
482 " but got %d", s->mode, mode); in replication_start()
486 switch (s->mode) { in replication_start()
491 active_disk = bs->file; in replication_start()
492 if (!active_disk || !active_disk->bs || !active_disk->bs->backing) { in replication_start()
498 hidden_disk = active_disk->bs->backing; in replication_start()
499 if (!hidden_disk->bs || !hidden_disk->bs->backing) { in replication_start()
505 secondary_disk = hidden_disk->bs->backing; in replication_start()
506 if (!secondary_disk->bs || !bdrv_has_blk(secondary_disk->bs)) { in replication_start()
514 active_length = bdrv_getlength(active_disk->bs); in replication_start()
515 hidden_length = bdrv_getlength(hidden_disk->bs); in replication_start()
516 disk_length = bdrv_getlength(secondary_disk->bs); in replication_start()
519 error_setg(errp, "Active disk, hidden disk, secondary disk's length" in replication_start()
525 assert(active_disk->bs->drv && hidden_disk->bs->drv); in replication_start()
528 if (!active_disk->bs->drv->bdrv_make_empty || in replication_start()
529 !hidden_disk->bs->drv->bdrv_make_empty) { in replication_start()
537 /* reopen the backing file in r/w mode */ in replication_start()
546 bdrv_ref(hidden_disk->bs); in replication_start()
547 s->hidden_disk = bdrv_attach_child(bs, hidden_disk->bs, "hidden disk", in replication_start()
556 bdrv_ref(secondary_disk->bs); in replication_start()
557 s->secondary_disk = bdrv_attach_child(bs, secondary_disk->bs, in replication_start()
567 error_setg(&s->blocker, in replication_start()
570 top_bs = bdrv_lookup_bs(s->top_id, s->top_id, NULL); in replication_start()
578 bdrv_op_block_all(top_bs, s->blocker); in replication_start()
582 s->backup_job = backup_job_create( in replication_start()
583 NULL, s->secondary_disk->bs, s->hidden_disk->bs, in replication_start()
594 job_start(&s->backup_job->job); in replication_start()
600 s->stage = BLOCK_REPLICATION_RUNNING; in replication_start()
602 if (s->mode == REPLICATION_MODE_SECONDARY) { in replication_start()
606 s->error = 0; in replication_start()
611 BlockDriverState *bs = rs->opaque; in replication_do_checkpoint()
612 BDRVReplicationState *s = bs->opaque; in replication_do_checkpoint() local
614 if (s->stage == BLOCK_REPLICATION_DONE || in replication_do_checkpoint()
615 s->stage == BLOCK_REPLICATION_FAILOVER) { in replication_do_checkpoint()
624 if (s->mode == REPLICATION_MODE_SECONDARY) { in replication_do_checkpoint()
631 BlockDriverState *bs = rs->opaque; in replication_get_error()
632 BDRVReplicationState *s = bs->opaque; in replication_get_error() local
634 if (s->stage == BLOCK_REPLICATION_NONE) { in replication_get_error()
639 if (s->error) { in replication_get_error()
648 BDRVReplicationState *s = bs->opaque; in replication_done() local
651 s->stage = BLOCK_REPLICATION_DONE; in replication_done()
654 bdrv_unref_child(bs, s->secondary_disk); in replication_done()
655 s->secondary_disk = NULL; in replication_done()
656 bdrv_unref_child(bs, s->hidden_disk); in replication_done()
657 s->hidden_disk = NULL; in replication_done()
660 s->error = 0; in replication_done()
662 s->stage = BLOCK_REPLICATION_FAILOVER_FAILED; in replication_done()
663 s->error = -EIO; in replication_done()
669 BlockDriverState *bs = rs->opaque; in replication_stop()
670 BDRVReplicationState *s = bs->opaque; in replication_stop() local
672 if (s->stage == BLOCK_REPLICATION_DONE || in replication_stop()
673 s->stage == BLOCK_REPLICATION_FAILOVER) { in replication_stop()
682 if (s->stage != BLOCK_REPLICATION_RUNNING) { in replication_stop()
687 switch (s->mode) { in replication_stop()
689 s->stage = BLOCK_REPLICATION_DONE; in replication_stop()
690 s->error = 0; in replication_stop()
698 if (s->backup_job) { in replication_stop()
699 job_cancel_sync(&s->backup_job->job, true); in replication_stop()
704 s->stage = BLOCK_REPLICATION_DONE; in replication_stop()
709 s->stage = BLOCK_REPLICATION_FAILOVER; in replication_stop()
710 s->commit_job = commit_active_start( in replication_stop()
711 NULL, bs->file->bs, s->secondary_disk->bs, in replication_stop()