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