Commit 4dfbe376 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging



Pull request

v2:
 * Fixed qcow2 sanitizer warnings [Peter]
 * Renamed get_error test cases to get_error_all to avoid tripping "error:"
   grep scripts [Peter]
 * Added Fam's iothread stop patch

# gpg: Signature made Tue 13 Sep 2016 11:02:30 BST
# gpg:                using RSA key 0x9CA4ABB381AB73C8
# gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>"
# gpg:                 aka "Stefan Hajnoczi <stefanha@gmail.com>"
# Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35  775A 9CA4 ABB3 81AB 73C8

* remotes/stefanha/tags/block-pull-request:
  iothread: Stop threads before main() quits
  tests: fix qvirtqueue_kick
  MAINTAINERS: add maintainer for replication
  support replication driver in blockdev-add
  tests: add unit test case for replication
  replication: Implement new driver for block replication
  replication: Introduce new APIs to do replication operation
  configure: support replication
  mirror: auto complete active commit
  docs: block replication's description
  block: Link backup into block core
  Backup: export interfaces for extra serialization
  Backup: clear all bitmap when doing block checkpoint
  block: unblock backup operations in backing file
  virtio-blk: rename virtio_device_info to virtio_blk_info
  linux-aio: process completions from ioq_submit()
  linux-aio: split processing events function
  linux-aio: consume events in userspace instead of calling io_getevents
  qcow2: avoid memcpy(dst, NULL, len)

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents fa970124 dce8921b
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -1624,6 +1624,15 @@ L: qemu-block@nongnu.org
S: Supported
F: tests/image-fuzzer/

Replication
M: Wen Congyang <wency@cn.fujitsu.com>
M: Changlong Xie <xiecl.fnst@cn.fujitsu.com>
S: Supported
F: replication*
F: block/replication.c
F: tests/test-replication.c
F: docs/block-replication.txt

Build and test automation
-------------------------
M: Alex Bennée <alex.bennee@linaro.org>
+1 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ block-obj-$(CONFIG_POSIX) += aio-posix.o
block-obj-$(CONFIG_WIN32) += aio-win32.o
block-obj-y += block/
block-obj-y += qemu-io-cmds.o
block-obj-$(CONFIG_REPLICATION) += replication.o

block-obj-m = block/

+17 −0
Original line number Diff line number Diff line
@@ -1312,6 +1312,23 @@ void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd)
    /* Otherwise we won't be able to commit due to check in bdrv_commit */
    bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_COMMIT_TARGET,
                    bs->backing_blocker);
    /*
     * We do backup in 3 ways:
     * 1. drive backup
     *    The target bs is new opened, and the source is top BDS
     * 2. blockdev backup
     *    Both the source and the target are top BDSes.
     * 3. internal backup(used for block replication)
     *    Both the source and the target are backing file
     *
     * In case 1 and 2, neither the source nor the target is the backing file.
     * In case 3, we will block the top BDS, so there is only one block job
     * for the top BDS and its backing chain.
     */
    bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_BACKUP_SOURCE,
                    bs->backing_blocker);
    bdrv_op_unblock(backing_hd, BLOCK_OP_TYPE_BACKUP_TARGET,
                    bs->backing_blocker);
out:
    bdrv_refresh_limits(bs, NULL);
}
+2 −1
Original line number Diff line number Diff line
@@ -22,11 +22,12 @@ block-obj-$(CONFIG_ARCHIPELAGO) += archipelago.o
block-obj-$(CONFIG_LIBSSH2) += ssh.o
block-obj-y += accounting.o dirty-bitmap.o
block-obj-y += write-threshold.o
block-obj-y += backup.o
block-obj-$(CONFIG_REPLICATION) += replication.o

block-obj-y += crypto.o

common-obj-y += stream.o
common-obj-y += backup.o

iscsi.o-cflags     := $(LIBISCSI_CFLAGS)
iscsi.o-libs       := $(LIBISCSI_LIBS)
+52 −7
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "block/block.h"
#include "block/block_int.h"
#include "block/blockjob.h"
#include "block/block_backup.h"
#include "qapi/error.h"
#include "qapi/qmp/qerror.h"
#include "qemu/ratelimit.h"
@@ -27,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;
@@ -255,6 +249,57 @@ static void backup_attached_aio_context(BlockJob *job, AioContext *aio_context)
    blk_set_aio_context(s->target, aio_context);
}

void backup_do_checkpoint(BlockJob *job, Error **errp)
{
    BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
    int64_t len;

    assert(job->driver->job_type == BLOCK_JOB_TYPE_BACKUP);

    if (backup_job->sync_mode != MIRROR_SYNC_MODE_NONE) {
        error_setg(errp, "The backup job only supports block checkpoint in"
                   " sync=none mode");
        return;
    }

    len = DIV_ROUND_UP(backup_job->common.len, backup_job->cluster_size);
    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,
Loading