From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55236) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UoQLp-0002RF-Kx for qemu-devel@nongnu.org; Sun, 16 Jun 2013 23:43:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UoQLm-0005sH-TY for qemu-devel@nongnu.org; Sun, 16 Jun 2013 23:43:29 -0400 Received: from mx1.redhat.com ([209.132.183.28]:30535) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UoQLm-0005s5-Lt for qemu-devel@nongnu.org; Sun, 16 Jun 2013 23:43:26 -0400 Date: Mon, 17 Jun 2013 11:43:24 +0800 From: Fam Zheng Message-ID: <20130617034324.GA10271@localhost.nay.redhat.com> References: <1369917299-5725-1-git-send-email-stefanha@redhat.com> <1369917299-5725-4-git-send-email-stefanha@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1369917299-5725-4-git-send-email-stefanha@redhat.com> Subject: Re: [Qemu-devel] [PATCH v5 03/11] block: add basic backup support to block driver List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Stefan Hajnoczi Cc: Kevin Wolf , qemu-devel@nongnu.org, dietmar@proxmox.com, imain@redhat.com, Paolo Bonzini , xiawenc@linux.vnet.ibm.com > +static void coroutine_fn backup_run(void *opaque) > +{ > + BackupBlockJob *job = opaque; > + BlockDriverState *bs = job->common.bs; > + BlockDriverState *target = job->target; > + BlockdevOnError on_target_error = job->on_target_error; > + NotifierWithReturn before_write = { > + .notify = backup_before_write_notify, > + }; > + int64_t start, end; > + int ret = 0; > + > + QLIST_INIT(&job->inflight_reqs); > + qemu_co_rwlock_init(&job->flush_rwlock); > + > + start = 0; > + end = DIV_ROUND_UP(bdrv_getlength(bs) / BDRV_SECTOR_SIZE, > + BACKUP_SECTORS_PER_CLUSTER); > + > + job->bitmap = hbitmap_alloc(end, 0); > + > + bdrv_set_on_error(target, on_target_error, on_target_error); > + bdrv_iostatus_enable(target); > + > + bdrv_add_before_write_notifier(bs, &before_write); > + > + DPRINTF("backup_run start %s %" PRId64 " %" PRId64 "\n", > + bdrv_get_device_name(bs), start, end); > + > + for (; start < end; start++) { > + bool error_is_read; > + > + if (block_job_is_cancelled(&job->common)) { > + break; > + } > + > + /* we need to yield so that qemu_aio_flush() returns. > + * (without, VM does not reboot) > + */ > + if (job->common.speed) { > + uint64_t delay_ns = ratelimit_calculate_delay( > + &job->limit, job->sectors_read); > + job->sectors_read = 0; > + block_job_sleep_ns(&job->common, rt_clock, delay_ns); > + } else { > + block_job_sleep_ns(&job->common, rt_clock, 0); > + } > + > + if (block_job_is_cancelled(&job->common)) { > + break; > + } > + > + DPRINTF("backup_run loop C%" PRId64 "\n", start); > + > + ret = backup_do_cow(bs, start * BACKUP_SECTORS_PER_CLUSTER, 1, > + &error_is_read); > + if (ret < 0) { > + /* Depending on error action, fail now or retry cluster */ > + BlockErrorAction action = > + backup_error_action(job, error_is_read, -ret); > + if (action == BDRV_ACTION_REPORT) { > + break; > + } else { > + start--; > + continue; > + } > + } > + } > + > + notifier_with_return_remove(&before_write); > + > + /* wait until pending backup_do_cow() calls have completed */ > + qemu_co_rwlock_wrlock(&job->flush_rwlock); > + qemu_co_rwlock_unlock(&job->flush_rwlock); > + > + hbitmap_free(job->bitmap); > + > + bdrv_iostatus_disable(target); > + bdrv_delete(job->target); drive-mirror has bdrv_close before deleting target, why don't we need one here? > + > + DPRINTF("backup_run complete %d\n", ret); > + block_job_completed(&job->common, ret); > +} > + Fam