From 98d2c6f2cd80afaa2dc10091f5e35a97c181e4f5 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Mon, 24 Jun 2013 17:13:11 +0200 Subject: block: add basic backup support to block driver backup_start() creates a block job that copies a point-in-time snapshot of a block device to a target block device. We call backup_do_cow() for each write during backup. That function reads the original data from the block device before it gets overwritten. The data is then written to the target device. Currently backup cluster size is hardcoded to 65536 bytes. [I made a number of changes to Dietmar's original patch and folded them in to make code review easy. Here is the full list: * Drop BackupDumpFunc interface in favor of a target block device * Detect zero clusters with buffer_is_zero() and use bdrv_co_write_zeroes() * Use 0 delay instead of 1us, like other block jobs * Unify creation/start functions into backup_start() * Simplify cleanup, free bitmap in backup_run() instead of cb * function * Use HBitmap to avoid duplicating bitmap code * Use bdrv_getlength() instead of accessing ->total_sectors * directly * Delete the backup.h header file, it is no longer necessary * Move ./backup.c to block/backup.c * Remove #ifdefed out code * Coding style and whitespace cleanups * Use bdrv_add_before_write_notifier() instead of blockjob-specific hooks * Keep our own in-flight CowRequest list instead of using block.c tracked requests. This means a little code duplication but is much simpler than trying to share the tracked requests list and use the backup block size. * Add on_source_error and on_target_error error handling. * Use trace events instead of DPRINTF() -- stefanha] Signed-off-by: Dietmar Maurer Signed-off-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf --- trace-events | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'trace-events') diff --git a/trace-events b/trace-events index c5f1ccb96d..0acce7b350 100644 --- a/trace-events +++ b/trace-events @@ -92,6 +92,14 @@ mirror_yield_in_flight(void *s, int64_t sector_num, int in_flight) "s %p sector_ mirror_yield_buf_busy(void *s, int nb_chunks, int in_flight) "s %p requested chunks %d in_flight %d" mirror_break_buf_busy(void *s, int nb_chunks, int in_flight) "s %p requested chunks %d in_flight %d" +# block/backup.c +backup_do_cow_enter(void *job, int64_t start, int64_t sector_num, int nb_sectors) "job %p start %"PRId64" sector_num %"PRId64" nb_sectors %d" +backup_do_cow_return(void *job, int64_t sector_num, int nb_sectors, int ret) "job %p sector_num %"PRId64" nb_sectors %d ret %d" +backup_do_cow_skip(void *job, int64_t start) "job %p start %"PRId64 +backup_do_cow_process(void *job, int64_t start) "job %p start %"PRId64 +backup_do_cow_read_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d" +backup_do_cow_write_fail(void *job, int64_t start, int ret) "job %p start %"PRId64" ret %d" + # blockdev.c qmp_block_job_cancel(void *job) "job %p" qmp_block_job_pause(void *job) "job %p" -- cgit v1.2.1