xref: /openbmc/qemu/block/replication.c (revision 7a1bfee6)
1 /*
2  * Replication Block filter
3  *
4  * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
5  * Copyright (c) 2016 Intel Corporation
6  * Copyright (c) 2016 FUJITSU LIMITED
7  *
8  * Author:
9  *   Wen Congyang <wency@cn.fujitsu.com>
10  *
11  * This work is licensed under the terms of the GNU GPL, version 2 or later.
12  * See the COPYING file in the top-level directory.
13  */
14 
15 #include "qemu/osdep.h"
16 #include "qemu/module.h"
17 #include "qemu/option.h"
18 #include "block/nbd.h"
19 #include "block/blockjob.h"
20 #include "block/block_int.h"
21 #include "block/block_backup.h"
22 #include "sysemu/block-backend.h"
23 #include "qapi/error.h"
24 #include "qapi/qmp/qdict.h"
25 #include "replication.h"
26 
27 typedef enum {
28     BLOCK_REPLICATION_NONE,             /* block replication is not started */
29     BLOCK_REPLICATION_RUNNING,          /* block replication is running */
30     BLOCK_REPLICATION_FAILOVER,         /* failover is running in background */
31     BLOCK_REPLICATION_FAILOVER_FAILED,  /* failover failed */
32     BLOCK_REPLICATION_DONE,             /* block replication is done */
33 } ReplicationStage;
34 
35 typedef struct BDRVReplicationState {
36     ReplicationMode mode;
37     ReplicationStage stage;
38     BdrvChild *active_disk;
39     BlockJob *commit_job;
40     BdrvChild *hidden_disk;
41     BdrvChild *secondary_disk;
42     BlockJob *backup_job;
43     char *top_id;
44     ReplicationState *rs;
45     Error *blocker;
46     bool orig_hidden_read_only;
47     bool orig_secondary_read_only;
48     int error;
49 } BDRVReplicationState;
50 
51 static void replication_start(ReplicationState *rs, ReplicationMode mode,
52                               Error **errp);
53 static void replication_do_checkpoint(ReplicationState *rs, Error **errp);
54 static void replication_get_error(ReplicationState *rs, Error **errp);
55 static void replication_stop(ReplicationState *rs, bool failover,
56                              Error **errp);
57 
58 #define REPLICATION_MODE        "mode"
59 #define REPLICATION_TOP_ID      "top-id"
60 static QemuOptsList replication_runtime_opts = {
61     .name = "replication",
62     .head = QTAILQ_HEAD_INITIALIZER(replication_runtime_opts.head),
63     .desc = {
64         {
65             .name = REPLICATION_MODE,
66             .type = QEMU_OPT_STRING,
67         },
68         {
69             .name = REPLICATION_TOP_ID,
70             .type = QEMU_OPT_STRING,
71         },
72         { /* end of list */ }
73     },
74 };
75 
76 static ReplicationOps replication_ops = {
77     .start = replication_start,
78     .checkpoint = replication_do_checkpoint,
79     .get_error = replication_get_error,
80     .stop = replication_stop,
81 };
82 
83 static int replication_open(BlockDriverState *bs, QDict *options,
84                             int flags, Error **errp)
85 {
86     int ret;
87     BDRVReplicationState *s = bs->opaque;
88     Error *local_err = NULL;
89     QemuOpts *opts = NULL;
90     const char *mode;
91     const char *top_id;
92 
93     bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
94                                false, errp);
95     if (!bs->file) {
96         return -EINVAL;
97     }
98 
99     ret = -EINVAL;
100     opts = qemu_opts_create(&replication_runtime_opts, NULL, 0, &error_abort);
101     qemu_opts_absorb_qdict(opts, options, &local_err);
102     if (local_err) {
103         goto fail;
104     }
105 
106     mode = qemu_opt_get(opts, REPLICATION_MODE);
107     if (!mode) {
108         error_setg(&local_err, "Missing the option mode");
109         goto fail;
110     }
111 
112     if (!strcmp(mode, "primary")) {
113         s->mode = REPLICATION_MODE_PRIMARY;
114         top_id = qemu_opt_get(opts, REPLICATION_TOP_ID);
115         if (top_id) {
116             error_setg(&local_err, "The primary side does not support option top-id");
117             goto fail;
118         }
119     } else if (!strcmp(mode, "secondary")) {
120         s->mode = REPLICATION_MODE_SECONDARY;
121         top_id = qemu_opt_get(opts, REPLICATION_TOP_ID);
122         s->top_id = g_strdup(top_id);
123         if (!s->top_id) {
124             error_setg(&local_err, "Missing the option top-id");
125             goto fail;
126         }
127     } else {
128         error_setg(&local_err,
129                    "The option mode's value should be primary or secondary");
130         goto fail;
131     }
132 
133     s->rs = replication_new(bs, &replication_ops);
134 
135     ret = 0;
136 
137 fail:
138     qemu_opts_del(opts);
139     error_propagate(errp, local_err);
140 
141     return ret;
142 }
143 
144 static void replication_close(BlockDriverState *bs)
145 {
146     BDRVReplicationState *s = bs->opaque;
147     Job *commit_job;
148 
149     if (s->stage == BLOCK_REPLICATION_RUNNING) {
150         replication_stop(s->rs, false, NULL);
151     }
152     if (s->stage == BLOCK_REPLICATION_FAILOVER) {
153         commit_job = &s->commit_job->job;
154         assert(commit_job->aio_context == qemu_get_current_aio_context());
155         job_cancel_sync(commit_job);
156     }
157 
158     if (s->mode == REPLICATION_MODE_SECONDARY) {
159         g_free(s->top_id);
160     }
161 
162     replication_remove(s->rs);
163 }
164 
165 static void replication_child_perm(BlockDriverState *bs, BdrvChild *c,
166                                    const BdrvChildRole *role,
167                                    BlockReopenQueue *reopen_queue,
168                                    uint64_t perm, uint64_t shared,
169                                    uint64_t *nperm, uint64_t *nshared)
170 {
171     *nperm = BLK_PERM_CONSISTENT_READ;
172     if ((bs->open_flags & (BDRV_O_INACTIVE | BDRV_O_RDWR)) == BDRV_O_RDWR) {
173         *nperm |= BLK_PERM_WRITE;
174     }
175     *nshared = BLK_PERM_CONSISTENT_READ
176                | BLK_PERM_WRITE
177                | BLK_PERM_WRITE_UNCHANGED;
178     return;
179 }
180 
181 static int64_t replication_getlength(BlockDriverState *bs)
182 {
183     return bdrv_getlength(bs->file->bs);
184 }
185 
186 static int replication_get_io_status(BDRVReplicationState *s)
187 {
188     switch (s->stage) {
189     case BLOCK_REPLICATION_NONE:
190         return -EIO;
191     case BLOCK_REPLICATION_RUNNING:
192         return 0;
193     case BLOCK_REPLICATION_FAILOVER:
194         return s->mode == REPLICATION_MODE_PRIMARY ? -EIO : 0;
195     case BLOCK_REPLICATION_FAILOVER_FAILED:
196         return s->mode == REPLICATION_MODE_PRIMARY ? -EIO : 1;
197     case BLOCK_REPLICATION_DONE:
198         /*
199          * active commit job completes, and active disk and secondary_disk
200          * is swapped, so we can operate bs->file directly
201          */
202         return s->mode == REPLICATION_MODE_PRIMARY ? -EIO : 0;
203     default:
204         abort();
205     }
206 }
207 
208 static int replication_return_value(BDRVReplicationState *s, int ret)
209 {
210     if (s->mode == REPLICATION_MODE_SECONDARY) {
211         return ret;
212     }
213 
214     if (ret < 0) {
215         s->error = ret;
216         ret = 0;
217     }
218 
219     return ret;
220 }
221 
222 static coroutine_fn int replication_co_readv(BlockDriverState *bs,
223                                              int64_t sector_num,
224                                              int remaining_sectors,
225                                              QEMUIOVector *qiov)
226 {
227     BDRVReplicationState *s = bs->opaque;
228     int ret;
229 
230     if (s->mode == REPLICATION_MODE_PRIMARY) {
231         /* We only use it to forward primary write requests */
232         return -EIO;
233     }
234 
235     ret = replication_get_io_status(s);
236     if (ret < 0) {
237         return ret;
238     }
239 
240     ret = bdrv_co_preadv(bs->file, sector_num * BDRV_SECTOR_SIZE,
241                          remaining_sectors * BDRV_SECTOR_SIZE, qiov, 0);
242 
243     return replication_return_value(s, ret);
244 }
245 
246 static coroutine_fn int replication_co_writev(BlockDriverState *bs,
247                                               int64_t sector_num,
248                                               int remaining_sectors,
249                                               QEMUIOVector *qiov,
250                                               int flags)
251 {
252     BDRVReplicationState *s = bs->opaque;
253     QEMUIOVector hd_qiov;
254     uint64_t bytes_done = 0;
255     BdrvChild *top = bs->file;
256     BdrvChild *base = s->secondary_disk;
257     BdrvChild *target;
258     int ret;
259     int64_t n;
260 
261     assert(!flags);
262     ret = replication_get_io_status(s);
263     if (ret < 0) {
264         goto out;
265     }
266 
267     if (ret == 0) {
268         ret = bdrv_co_pwritev(top, sector_num * BDRV_SECTOR_SIZE,
269                               remaining_sectors * BDRV_SECTOR_SIZE, qiov, 0);
270         return replication_return_value(s, ret);
271     }
272 
273     /*
274      * Failover failed, only write to active disk if the sectors
275      * have already been allocated in active disk/hidden disk.
276      */
277     qemu_iovec_init(&hd_qiov, qiov->niov);
278     while (remaining_sectors > 0) {
279         int64_t count;
280 
281         ret = bdrv_is_allocated_above(top->bs, base->bs, false,
282                                       sector_num * BDRV_SECTOR_SIZE,
283                                       remaining_sectors * BDRV_SECTOR_SIZE,
284                                       &count);
285         if (ret < 0) {
286             goto out1;
287         }
288 
289         assert(QEMU_IS_ALIGNED(count, BDRV_SECTOR_SIZE));
290         n = count >> BDRV_SECTOR_BITS;
291         qemu_iovec_reset(&hd_qiov);
292         qemu_iovec_concat(&hd_qiov, qiov, bytes_done, count);
293 
294         target = ret ? top : base;
295         ret = bdrv_co_pwritev(target, sector_num * BDRV_SECTOR_SIZE,
296                               n * BDRV_SECTOR_SIZE, &hd_qiov, 0);
297         if (ret < 0) {
298             goto out1;
299         }
300 
301         remaining_sectors -= n;
302         sector_num += n;
303         bytes_done += count;
304     }
305 
306 out1:
307     qemu_iovec_destroy(&hd_qiov);
308 out:
309     return ret;
310 }
311 
312 static void secondary_do_checkpoint(BDRVReplicationState *s, Error **errp)
313 {
314     Error *local_err = NULL;
315     int ret;
316 
317     if (!s->backup_job) {
318         error_setg(errp, "Backup job was cancelled unexpectedly");
319         return;
320     }
321 
322     backup_do_checkpoint(s->backup_job, &local_err);
323     if (local_err) {
324         error_propagate(errp, local_err);
325         return;
326     }
327 
328     if (!s->active_disk->bs->drv) {
329         error_setg(errp, "Active disk %s is ejected",
330                    s->active_disk->bs->node_name);
331         return;
332     }
333 
334     ret = s->active_disk->bs->drv->bdrv_make_empty(s->active_disk->bs);
335     if (ret < 0) {
336         error_setg(errp, "Cannot make active disk empty");
337         return;
338     }
339 
340     if (!s->hidden_disk->bs->drv) {
341         error_setg(errp, "Hidden disk %s is ejected",
342                    s->hidden_disk->bs->node_name);
343         return;
344     }
345 
346     ret = s->hidden_disk->bs->drv->bdrv_make_empty(s->hidden_disk->bs);
347     if (ret < 0) {
348         error_setg(errp, "Cannot make hidden disk empty");
349         return;
350     }
351 }
352 
353 /* This function is supposed to be called twice:
354  * first with writable = true, then with writable = false.
355  * The first call puts s->hidden_disk and s->secondary_disk in
356  * r/w mode, and the second puts them back in their original state.
357  */
358 static void reopen_backing_file(BlockDriverState *bs, bool writable,
359                                 Error **errp)
360 {
361     BDRVReplicationState *s = bs->opaque;
362     BlockReopenQueue *reopen_queue = NULL;
363     Error *local_err = NULL;
364 
365     if (writable) {
366         s->orig_hidden_read_only = bdrv_is_read_only(s->hidden_disk->bs);
367         s->orig_secondary_read_only = bdrv_is_read_only(s->secondary_disk->bs);
368     }
369 
370     bdrv_subtree_drained_begin(s->hidden_disk->bs);
371     bdrv_subtree_drained_begin(s->secondary_disk->bs);
372 
373     if (s->orig_hidden_read_only) {
374         QDict *opts = qdict_new();
375         qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !writable);
376         reopen_queue = bdrv_reopen_queue(reopen_queue, s->hidden_disk->bs,
377                                          opts, true);
378     }
379 
380     if (s->orig_secondary_read_only) {
381         QDict *opts = qdict_new();
382         qdict_put_bool(opts, BDRV_OPT_READ_ONLY, !writable);
383         reopen_queue = bdrv_reopen_queue(reopen_queue, s->secondary_disk->bs,
384                                          opts, true);
385     }
386 
387     if (reopen_queue) {
388         bdrv_reopen_multiple(reopen_queue, &local_err);
389         error_propagate(errp, local_err);
390     }
391 
392     bdrv_subtree_drained_end(s->hidden_disk->bs);
393     bdrv_subtree_drained_end(s->secondary_disk->bs);
394 }
395 
396 static void backup_job_cleanup(BlockDriverState *bs)
397 {
398     BDRVReplicationState *s = bs->opaque;
399     BlockDriverState *top_bs;
400 
401     top_bs = bdrv_lookup_bs(s->top_id, s->top_id, NULL);
402     if (!top_bs) {
403         return;
404     }
405     bdrv_op_unblock_all(top_bs, s->blocker);
406     error_free(s->blocker);
407     reopen_backing_file(bs, false, NULL);
408 }
409 
410 static void backup_job_completed(void *opaque, int ret)
411 {
412     BlockDriverState *bs = opaque;
413     BDRVReplicationState *s = bs->opaque;
414 
415     if (s->stage != BLOCK_REPLICATION_FAILOVER) {
416         /* The backup job is cancelled unexpectedly */
417         s->error = -EIO;
418     }
419 
420     backup_job_cleanup(bs);
421 }
422 
423 static bool check_top_bs(BlockDriverState *top_bs, BlockDriverState *bs)
424 {
425     BdrvChild *child;
426 
427     /* The bs itself is the top_bs */
428     if (top_bs == bs) {
429         return true;
430     }
431 
432     /* Iterate over top_bs's children */
433     QLIST_FOREACH(child, &top_bs->children, next) {
434         if (child->bs == bs || check_top_bs(child->bs, bs)) {
435             return true;
436         }
437     }
438 
439     return false;
440 }
441 
442 static void replication_start(ReplicationState *rs, ReplicationMode mode,
443                               Error **errp)
444 {
445     BlockDriverState *bs = rs->opaque;
446     BDRVReplicationState *s;
447     BlockDriverState *top_bs;
448     int64_t active_length, hidden_length, disk_length;
449     AioContext *aio_context;
450     Error *local_err = NULL;
451 
452     aio_context = bdrv_get_aio_context(bs);
453     aio_context_acquire(aio_context);
454     s = bs->opaque;
455 
456     if (s->stage == BLOCK_REPLICATION_DONE ||
457         s->stage == BLOCK_REPLICATION_FAILOVER) {
458         /*
459          * This case happens when a secondary is promoted to primary.
460          * Ignore the request because the secondary side of replication
461          * doesn't have to do anything anymore.
462          */
463         aio_context_release(aio_context);
464         return;
465     }
466 
467     if (s->stage != BLOCK_REPLICATION_NONE) {
468         error_setg(errp, "Block replication is running or done");
469         aio_context_release(aio_context);
470         return;
471     }
472 
473     if (s->mode != mode) {
474         error_setg(errp, "The parameter mode's value is invalid, needs %d,"
475                    " but got %d", s->mode, mode);
476         aio_context_release(aio_context);
477         return;
478     }
479 
480     switch (s->mode) {
481     case REPLICATION_MODE_PRIMARY:
482         break;
483     case REPLICATION_MODE_SECONDARY:
484         s->active_disk = bs->file;
485         if (!s->active_disk || !s->active_disk->bs ||
486                                     !s->active_disk->bs->backing) {
487             error_setg(errp, "Active disk doesn't have backing file");
488             aio_context_release(aio_context);
489             return;
490         }
491 
492         s->hidden_disk = s->active_disk->bs->backing;
493         if (!s->hidden_disk->bs || !s->hidden_disk->bs->backing) {
494             error_setg(errp, "Hidden disk doesn't have backing file");
495             aio_context_release(aio_context);
496             return;
497         }
498 
499         s->secondary_disk = s->hidden_disk->bs->backing;
500         if (!s->secondary_disk->bs || !bdrv_has_blk(s->secondary_disk->bs)) {
501             error_setg(errp, "The secondary disk doesn't have block backend");
502             aio_context_release(aio_context);
503             return;
504         }
505 
506         /* verify the length */
507         active_length = bdrv_getlength(s->active_disk->bs);
508         hidden_length = bdrv_getlength(s->hidden_disk->bs);
509         disk_length = bdrv_getlength(s->secondary_disk->bs);
510         if (active_length < 0 || hidden_length < 0 || disk_length < 0 ||
511             active_length != hidden_length || hidden_length != disk_length) {
512             error_setg(errp, "Active disk, hidden disk, secondary disk's length"
513                        " are not the same");
514             aio_context_release(aio_context);
515             return;
516         }
517 
518         /* Must be true, or the bdrv_getlength() calls would have failed */
519         assert(s->active_disk->bs->drv && s->hidden_disk->bs->drv);
520 
521         if (!s->active_disk->bs->drv->bdrv_make_empty ||
522             !s->hidden_disk->bs->drv->bdrv_make_empty) {
523             error_setg(errp,
524                        "Active disk or hidden disk doesn't support make_empty");
525             aio_context_release(aio_context);
526             return;
527         }
528 
529         /* reopen the backing file in r/w mode */
530         reopen_backing_file(bs, true, &local_err);
531         if (local_err) {
532             error_propagate(errp, local_err);
533             aio_context_release(aio_context);
534             return;
535         }
536 
537         /* start backup job now */
538         error_setg(&s->blocker,
539                    "Block device is in use by internal backup job");
540 
541         top_bs = bdrv_lookup_bs(s->top_id, s->top_id, NULL);
542         if (!top_bs || !bdrv_is_root_node(top_bs) ||
543             !check_top_bs(top_bs, bs)) {
544             error_setg(errp, "No top_bs or it is invalid");
545             reopen_backing_file(bs, false, NULL);
546             aio_context_release(aio_context);
547             return;
548         }
549         bdrv_op_block_all(top_bs, s->blocker);
550         bdrv_op_unblock(top_bs, BLOCK_OP_TYPE_DATAPLANE, s->blocker);
551 
552         s->backup_job = backup_job_create(
553                                 NULL, s->secondary_disk->bs, s->hidden_disk->bs,
554                                 0, MIRROR_SYNC_MODE_NONE, NULL, 0, false, NULL,
555                                 BLOCKDEV_ON_ERROR_REPORT,
556                                 BLOCKDEV_ON_ERROR_REPORT, JOB_INTERNAL,
557                                 backup_job_completed, bs, NULL, &local_err);
558         if (local_err) {
559             error_propagate(errp, local_err);
560             backup_job_cleanup(bs);
561             aio_context_release(aio_context);
562             return;
563         }
564         job_start(&s->backup_job->job);
565         break;
566     default:
567         aio_context_release(aio_context);
568         abort();
569     }
570 
571     s->stage = BLOCK_REPLICATION_RUNNING;
572 
573     if (s->mode == REPLICATION_MODE_SECONDARY) {
574         secondary_do_checkpoint(s, errp);
575     }
576 
577     s->error = 0;
578     aio_context_release(aio_context);
579 }
580 
581 static void replication_do_checkpoint(ReplicationState *rs, Error **errp)
582 {
583     BlockDriverState *bs = rs->opaque;
584     BDRVReplicationState *s;
585     AioContext *aio_context;
586 
587     aio_context = bdrv_get_aio_context(bs);
588     aio_context_acquire(aio_context);
589     s = bs->opaque;
590 
591     if (s->stage == BLOCK_REPLICATION_DONE ||
592         s->stage == BLOCK_REPLICATION_FAILOVER) {
593         /*
594          * This case happens when a secondary was promoted to primary.
595          * Ignore the request because the secondary side of replication
596          * doesn't have to do anything anymore.
597          */
598         aio_context_release(aio_context);
599         return;
600     }
601 
602     if (s->mode == REPLICATION_MODE_SECONDARY) {
603         secondary_do_checkpoint(s, errp);
604     }
605     aio_context_release(aio_context);
606 }
607 
608 static void replication_get_error(ReplicationState *rs, Error **errp)
609 {
610     BlockDriverState *bs = rs->opaque;
611     BDRVReplicationState *s;
612     AioContext *aio_context;
613 
614     aio_context = bdrv_get_aio_context(bs);
615     aio_context_acquire(aio_context);
616     s = bs->opaque;
617 
618     if (s->stage == BLOCK_REPLICATION_NONE) {
619         error_setg(errp, "Block replication is not running");
620         aio_context_release(aio_context);
621         return;
622     }
623 
624     if (s->error) {
625         error_setg(errp, "I/O error occurred");
626         aio_context_release(aio_context);
627         return;
628     }
629     aio_context_release(aio_context);
630 }
631 
632 static void replication_done(void *opaque, int ret)
633 {
634     BlockDriverState *bs = opaque;
635     BDRVReplicationState *s = bs->opaque;
636 
637     if (ret == 0) {
638         s->stage = BLOCK_REPLICATION_DONE;
639 
640         s->active_disk = NULL;
641         s->secondary_disk = NULL;
642         s->hidden_disk = NULL;
643         s->error = 0;
644     } else {
645         s->stage = BLOCK_REPLICATION_FAILOVER_FAILED;
646         s->error = -EIO;
647     }
648 }
649 
650 static void replication_stop(ReplicationState *rs, bool failover, Error **errp)
651 {
652     BlockDriverState *bs = rs->opaque;
653     BDRVReplicationState *s;
654     AioContext *aio_context;
655 
656     aio_context = bdrv_get_aio_context(bs);
657     aio_context_acquire(aio_context);
658     s = bs->opaque;
659 
660     if (s->stage == BLOCK_REPLICATION_DONE ||
661         s->stage == BLOCK_REPLICATION_FAILOVER) {
662         /*
663          * This case happens when a secondary was promoted to primary.
664          * Ignore the request because the secondary side of replication
665          * doesn't have to do anything anymore.
666          */
667         aio_context_release(aio_context);
668         return;
669     }
670 
671     if (s->stage != BLOCK_REPLICATION_RUNNING) {
672         error_setg(errp, "Block replication is not running");
673         aio_context_release(aio_context);
674         return;
675     }
676 
677     switch (s->mode) {
678     case REPLICATION_MODE_PRIMARY:
679         s->stage = BLOCK_REPLICATION_DONE;
680         s->error = 0;
681         break;
682     case REPLICATION_MODE_SECONDARY:
683         /*
684          * This BDS will be closed, and the job should be completed
685          * before the BDS is closed, because we will access hidden
686          * disk, secondary disk in backup_job_completed().
687          */
688         if (s->backup_job) {
689             job_cancel_sync(&s->backup_job->job);
690         }
691 
692         if (!failover) {
693             secondary_do_checkpoint(s, errp);
694             s->stage = BLOCK_REPLICATION_DONE;
695             aio_context_release(aio_context);
696             return;
697         }
698 
699         s->stage = BLOCK_REPLICATION_FAILOVER;
700         s->commit_job = commit_active_start(
701                             NULL, s->active_disk->bs, s->secondary_disk->bs,
702                             JOB_INTERNAL, 0, BLOCKDEV_ON_ERROR_REPORT,
703                             NULL, replication_done, bs, true, errp);
704         break;
705     default:
706         aio_context_release(aio_context);
707         abort();
708     }
709     aio_context_release(aio_context);
710 }
711 
712 static const char *const replication_strong_runtime_opts[] = {
713     REPLICATION_MODE,
714     REPLICATION_TOP_ID,
715 
716     NULL
717 };
718 
719 static BlockDriver bdrv_replication = {
720     .format_name                = "replication",
721     .instance_size              = sizeof(BDRVReplicationState),
722 
723     .bdrv_open                  = replication_open,
724     .bdrv_close                 = replication_close,
725     .bdrv_child_perm            = replication_child_perm,
726 
727     .bdrv_getlength             = replication_getlength,
728     .bdrv_co_readv              = replication_co_readv,
729     .bdrv_co_writev             = replication_co_writev,
730 
731     .is_filter                  = true,
732 
733     .has_variable_length        = true,
734     .strong_runtime_opts        = replication_strong_runtime_opts,
735 };
736 
737 static void bdrv_replication_init(void)
738 {
739     bdrv_register(&bdrv_replication);
740 }
741 
742 block_init(bdrv_replication_init);
743