diff mbox series

[v3,14/18] block/fleecing-hook: internal api

Message ID 20181001102928.20533-15-vsementsov@virtuozzo.com
State New
Headers show
Series fleecing-hook driver for backup | expand

Commit Message

Vladimir Sementsov-Ogievskiy Oct. 1, 2018, 10:29 a.m. UTC
Add some functions to use fleecing-hook internally from backup job in
further commit.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 include/block/block.h |  9 ++++++++
 block/fleecing-hook.c | 51 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

Comments

Kevin Wolf Oct. 4, 2018, 12:50 p.m. UTC | #1
Am 01.10.2018 um 12:29 hat Vladimir Sementsov-Ogievskiy geschrieben:
> Add some functions to use fleecing-hook internally from backup job in
> further commit.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
> ---
>  include/block/block.h |  9 ++++++++
>  block/fleecing-hook.c | 51 +++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 60 insertions(+)
> 
> diff --git a/include/block/block.h b/include/block/block.h
> index 4edc1e8afa..018751b6ea 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -710,4 +710,13 @@ int coroutine_fn bdrv_co_copy_range(BdrvChild *src, uint64_t src_offset,
>                                      BdrvChild *dst, uint64_t dst_offset,
>                                      uint64_t bytes, BdrvRequestFlags read_flags,
>                                      BdrvRequestFlags write_flags);
> +
> +
> +BlockDriverState *bdrv_fleecing_hook_append(BlockDriverState *source,
> +                                            BlockDriverState *target,
> +                                            const char *copy_bitmap_name,
> +                                            Error **errp);
> +void bdrv_fleecing_hook_drop(BlockDriverState *hook);
> +uint64_t bdrv_fleecing_hook_progress(BlockDriverState *hook);

Public block.h interfaces that are specific to a single driver are bad
design. If at all possible, the generic block layer shouldn't know
anything about specific drivers.

Luckily, if you make the driver more consistent with what mirror and
commit are doing, you won't need public interfaces any more and the
functions will just become part of the backup job driver. (The backup
driver can still be split into multiple source files if necessary, and
then use a separate internal header; I'm not sure if this is the case
here, though.)

Kevin
diff mbox series

Patch

diff --git a/include/block/block.h b/include/block/block.h
index 4edc1e8afa..018751b6ea 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -710,4 +710,13 @@  int coroutine_fn bdrv_co_copy_range(BdrvChild *src, uint64_t src_offset,
                                     BdrvChild *dst, uint64_t dst_offset,
                                     uint64_t bytes, BdrvRequestFlags read_flags,
                                     BdrvRequestFlags write_flags);
+
+
+BlockDriverState *bdrv_fleecing_hook_append(BlockDriverState *source,
+                                            BlockDriverState *target,
+                                            const char *copy_bitmap_name,
+                                            Error **errp);
+void bdrv_fleecing_hook_drop(BlockDriverState *hook);
+uint64_t bdrv_fleecing_hook_progress(BlockDriverState *hook);
+
 #endif
diff --git a/block/fleecing-hook.c b/block/fleecing-hook.c
index f4e2f3ce83..1471b985b2 100644
--- a/block/fleecing-hook.c
+++ b/block/fleecing-hook.c
@@ -34,6 +34,8 @@  typedef struct BDRVFleecingHookState {
                                     on guest write. */
     BdrvChild *target;
     bool cbw_bitmap_created;
+
+    uint64_t bytes_copied;
 } BDRVFleecingHookState;
 
 static coroutine_fn int fleecing_hook_co_preadv(
@@ -98,6 +100,7 @@  static coroutine_fn int fleecing_hook_cbw(BlockDriverState *bs, uint64_t offset,
             goto finish;
         }
 
+        s->bytes_copied += len;
         off += len;
         if (off >= end) {
             break;
@@ -296,3 +299,51 @@  static void bdrv_fleecing_hook_init(void)
 }
 
 block_init(bdrv_fleecing_hook_init);
+
+BlockDriverState *bdrv_fleecing_hook_append(BlockDriverState *source,
+                                            BlockDriverState *target,
+                                            const char *copy_bitmap_name,
+                                            Error **errp)
+{
+    QDict *opts = qdict_new();
+
+    qdict_put_str(opts, "driver", "fleecing-hook");
+    qdict_put_str(opts, "append-to", bdrv_get_node_name(source));
+    qdict_put_str(opts, "target", bdrv_get_node_name(target));
+    if (copy_bitmap_name) {
+        qdict_put_str(opts, "copy-bitmap", copy_bitmap_name);
+    }
+
+    /* set defaults like qmp_blockdev_add */
+    qdict_put_str(opts, BDRV_OPT_CACHE_DIRECT, "off");
+    qdict_put_str(opts, BDRV_OPT_CACHE_NO_FLUSH, "off");
+    qdict_put_str(opts, BDRV_OPT_READ_ONLY, "off");
+
+    return bdrv_open(NULL, NULL, opts, 0, errp);
+}
+
+void bdrv_fleecing_hook_drop(BlockDriverState *hook)
+{
+    AioContext *aio_context = bdrv_get_aio_context(hook);
+
+    aio_context_acquire(aio_context);
+
+    bdrv_drained_begin(hook);
+
+    bdrv_child_try_set_perm(hook->backing, 0, BLK_PERM_ALL, &error_abort);
+    bdrv_replace_node(hook, backing_bs(hook), &error_abort);
+    bdrv_set_backing_hd(hook, NULL, &error_abort);
+
+    bdrv_drained_end(hook);
+
+    bdrv_unref(hook);
+
+    aio_context_release(aio_context);
+}
+
+uint64_t bdrv_fleecing_hook_progress(BlockDriverState *hook)
+{
+    BDRVFleecingHookState *s = hook->opaque;
+
+    return s->bytes_copied;
+}