[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL v2 08/19] Backup: export interfaces for extra seriali
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PULL v2 08/19] Backup: export interfaces for extra serialization |
Date: |
Tue, 13 Sep 2016 11:02:36 +0100 |
From: Changlong Xie <address@hidden>
Normal backup(sync='none') workflow:
step 1. NBD peformance I/O write from client to server
qcow2_co_writev
bdrv_co_writev
...
bdrv_aligned_pwritev
notifier_with_return_list_notify -> backup_do_cow
bdrv_driver_pwritev // write new contents
step 2. drive-backup sync=none
backup_do_cow
{
wait_for_overlapping_requests
cow_request_begin
for(; start < end; start++) {
bdrv_co_readv_no_serialising //read old contents from Secondary disk
bdrv_co_writev // write old contents to hidden-disk
}
cow_request_end
}
step 3. Then roll back to "step 1" to write new contents to Secondary disk.
And for replication, we must make sure that we only read the old contents from
Secondary disk in order to keep contents consistent.
1) Replication workflow of Secondary
virtio-blk
^
-------> 1 NBD |
|| server 3 replication
|| ^ ^
|| | backing backing |
|| Secondary disk 6<-------- hidden-disk 5 <-------- active-disk 4
|| | ^
|| '-------------------------'
|| drive-backup sync=none 2
Hence, we need these interfaces to implement coarse-grained serialization
between
COW of Secondary disk and the read operation of replication.
Example codes about how to use them:
*#include "block/block_backup.h"
static coroutine_fn int xxx_co_readv()
{
CowRequest req;
BlockJob *job = secondary_disk->bs->job;
if (job) {
backup_wait_for_overlapping_requests(job, start, end);
backup_cow_request_begin(&req, job, start, end);
ret = bdrv_co_readv();
backup_cow_request_end(&req);
goto out;
}
ret = bdrv_co_readv();
out:
return ret;
}
Signed-off-by: Changlong Xie <address@hidden>
Signed-off-by: Wen Congyang <address@hidden>
Signed-off-by: Wang WeiWei <address@hidden>
Reviewed-by: Stefan Hajnoczi <address@hidden>
Message-id: address@hidden
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
block/backup.c | 41 ++++++++++++++++++++++++++++++++++-------
include/block/block_backup.h | 14 ++++++++++++++
2 files changed, 48 insertions(+), 7 deletions(-)
diff --git a/block/backup.c b/block/backup.c
index dbe54e2..582bd0f 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -28,13 +28,6 @@
#define BACKUP_CLUSTER_SIZE_DEFAULT (1 << 16)
#define SLICE_TIME 100000000ULL /* ns */
-typedef struct CowRequest {
- int64_t start;
- int64_t end;
- QLIST_ENTRY(CowRequest) list;
- CoQueue wait_queue; /* coroutines blocked on this request */
-} CowRequest;
-
typedef struct BackupBlockJob {
BlockJob common;
BlockBackend *target;
@@ -273,6 +266,40 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
bitmap_zero(backup_job->done_bitmap, len);
}
+void backup_wait_for_overlapping_requests(BlockJob *job, int64_t sector_num,
+ int nb_sectors)
+{
+ BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
+ int64_t sectors_per_cluster = cluster_size_sectors(backup_job);
+ int64_t start, end;
+
+ assert(job->driver->job_type == BLOCK_JOB_TYPE_BACKUP);
+
+ start = sector_num / sectors_per_cluster;
+ end = DIV_ROUND_UP(sector_num + nb_sectors, sectors_per_cluster);
+ wait_for_overlapping_requests(backup_job, start, end);
+}
+
+void backup_cow_request_begin(CowRequest *req, BlockJob *job,
+ int64_t sector_num,
+ int nb_sectors)
+{
+ BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
+ int64_t sectors_per_cluster = cluster_size_sectors(backup_job);
+ int64_t start, end;
+
+ assert(job->driver->job_type == BLOCK_JOB_TYPE_BACKUP);
+
+ start = sector_num / sectors_per_cluster;
+ end = DIV_ROUND_UP(sector_num + nb_sectors, sectors_per_cluster);
+ cow_request_begin(req, backup_job, start, end);
+}
+
+void backup_cow_request_end(CowRequest *req)
+{
+ cow_request_end(req);
+}
+
static const BlockJobDriver backup_job_driver = {
.instance_size = sizeof(BackupBlockJob),
.job_type = BLOCK_JOB_TYPE_BACKUP,
diff --git a/include/block/block_backup.h b/include/block/block_backup.h
index 157596c..8a75947 100644
--- a/include/block/block_backup.h
+++ b/include/block/block_backup.h
@@ -20,6 +20,20 @@
#include "block/block_int.h"
+typedef struct CowRequest {
+ int64_t start;
+ int64_t end;
+ QLIST_ENTRY(CowRequest) list;
+ CoQueue wait_queue; /* coroutines blocked on this request */
+} CowRequest;
+
+void backup_wait_for_overlapping_requests(BlockJob *job, int64_t sector_num,
+ int nb_sectors);
+void backup_cow_request_begin(CowRequest *req, BlockJob *job,
+ int64_t sector_num,
+ int nb_sectors);
+void backup_cow_request_end(CowRequest *req);
+
void backup_do_checkpoint(BlockJob *job, Error **errp);
#endif
--
2.7.4
- [Qemu-devel] [PULL v2 00/19] Block patches, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 01/19] qcow2: avoid memcpy(dst, NULL, len), Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 02/19] linux-aio: consume events in userspace instead of calling io_getevents, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 03/19] linux-aio: split processing events function, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 04/19] linux-aio: process completions from ioq_submit(), Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 05/19] virtio-blk: rename virtio_device_info to virtio_blk_info, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 06/19] block: unblock backup operations in backing file, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 07/19] Backup: clear all bitmap when doing block checkpoint, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 08/19] Backup: export interfaces for extra serialization,
Stefan Hajnoczi <=
- [Qemu-devel] [PULL v2 12/19] configure: support replication, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 09/19] block: Link backup into block core, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 13/19] replication: Introduce new APIs to do replication operation, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 10/19] docs: block replication's description, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 11/19] mirror: auto complete active commit, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 14/19] replication: Implement new driver for block replication, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 16/19] support replication driver in blockdev-add, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 15/19] tests: add unit test case for replication, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 17/19] MAINTAINERS: add maintainer for replication, Stefan Hajnoczi, 2016/09/13
- [Qemu-devel] [PULL v2 18/19] tests: fix qvirtqueue_kick, Stefan Hajnoczi, 2016/09/13