From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1N0fxB-0006mr-9y for qemu-devel@nongnu.org; Wed, 21 Oct 2009 14:30:33 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1N0fx6-0006jn-GV for qemu-devel@nongnu.org; Wed, 21 Oct 2009 14:30:32 -0400 Received: from [199.232.76.173] (port=60668 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1N0fx6-0006je-AZ for qemu-devel@nongnu.org; Wed, 21 Oct 2009 14:30:28 -0400 Received: from mail-ew0-f221.google.com ([209.85.219.221]:57792) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1N0fx5-0008Tm-JY for qemu-devel@nongnu.org; Wed, 21 Oct 2009 14:30:28 -0400 Received: by mail-ew0-f221.google.com with SMTP id 21so5568377ewy.8 for ; Wed, 21 Oct 2009 11:30:27 -0700 (PDT) Message-ID: <4ADF533E.30808@codemonkey.ws> Date: Wed, 21 Oct 2009 13:30:22 -0500 From: Anthony Liguori MIME-Version: 1.0 Subject: Re: [Qemu-devel] [PATCH 2/3 v4] Block live migration References: <12553645922863-git-send-email-lirans@il.ibm.com> In-Reply-To: <12553645922863-git-send-email-lirans@il.ibm.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: lirans@il.ibm.com Cc: qemu-devel@nongnu.org lirans@il.ibm.com wrote: > This patch introduces block migration called during live migration. Block > are being copied to the destination in an async way. First the code will > transfer the whole disk and then transfer all dirty blocks accumulted during > the migration. > Still need to improve transition from the iterative phase of migration to the > end phase. For now transition will take place when all blocks transfered once, > all the dirty blocks will be transfered during the end phase (guest is > suspended). > > > diff --git a/Makefile b/Makefile > index 7d4d75c..3f34459 100644 > --- a/Makefile > +++ b/Makefile > @@ -125,6 +125,7 @@ obj-y += qemu-char.o aio.o net-checksum.o savevm.o > obj-y += msmouse.o ps2.o > obj-y += qdev.o qdev-properties.o > obj-y += qint.o qstring.o qdict.o qlist.o qemu-config.o > +obj-y += block-migration.o > > obj-$(CONFIG_BRLAPI) += baum.o > obj-$(CONFIG_WIN32) += tap-win32.o > diff --git a/block-migration.c b/block-migration.c > new file mode 100644 > index 0000000..7ca9d85 > --- /dev/null > +++ b/block-migration.c > @@ -0,0 +1,624 @@ > +/* > + * QEMU live block migration > + * > + * Copyright IBM, Corp. 2009 > + * > + * Authors: > + * Liran Schour > + * > + * This work is licensed under the terms of the GNU GPL, version 2. See > + * the COPYING file in the top-level directory. > + * > + */ > + > +#include "qemu-common.h" > +#include "block_int.h" > +#include "hw/hw.h" > +#include "qemu-timer.h" > +#include "block-migration.h" > +#include > +#include > + > +#define SECTOR_BITS 9 > +#define SECTOR_SIZE (1 << SECTOR_BITS) > +#define SECTOR_MASK ~(SECTOR_SIZE - 1); > + > +#define SECTORS_PER_BLOCK 8 > +#define BLOCK_SIZE (SECTORS_PER_BLOCK << SECTOR_BITS) > + > +#define BLK_MIG_FLAG_DEVICE_BLOCK 0x01 > +#define BLK_MIG_FLAG_EOS 0x02 > + > +#define MAX_IS_ALLOCATED_SEARCH 65536 > +#define MAX_BLOCKS_READ 10000 > +#define BLOCKS_READ_CHANGE 100 > +#define INITIAL_BLOCKS_READ 100 > + > +//#define DEBUG_BLK_MIGRATION > + > +#ifdef DEBUG_BLK_MIGRATION > +#define dprintf(fmt, ...) \ > + do { printf("blk_migration: " fmt, ## __VA_ARGS__); } while (0) > +#else > +#define dprintf(fmt, ...) \ > + do { } while (0) > +#endif > + > +typedef struct BlkMigBlock { > + uint8_t buf[BLOCK_SIZE]; > + BlkMigDevState *bmds; > + int64_t sector; > + struct iovec iov; > + QEMUIOVector qiov; > + BlockDriverAIOCB *aiocb; > + int ret; > + struct BlkMigBlock *next; > +} BlkMigBlock; > + > +typedef struct BlkMigState { > + int bulk_completed; > + int blk_enable; > + int shared_base; > + int no_dirty; > + QEMUFile *load_file; > + BlkMigDevState *bmds_first; > + QEMUTimer *timer; > +} BlkMigState; > + > +static BlkMigState block_mig_state; > + > +static BlkMigBlock *first_blk = NULL; > +static BlkMigBlock *last_blk = NULL; > + > +static int submitted = 0; > +static int read_done = 0; > +static int transferred = 0; > It seems to me that this could all get moved to a global state (that's dynamically allocated). > + > +static int64_t print_completion = 0; > +static void mark_clean(BlkMigDevState *bmds, int64_t sector, > + int sector_num); > +static int is_dirty(BlkMigDevState *bmds, int64_t sector); > + > +static void blk_mig_read_cb(void *opaque, int ret) > +{ > + BlkMigBlock *blk = opaque; > + > + blk->ret = ret; > + > + /* insert at the end */ > + if(last_blk == NULL) { > + first_blk = last_blk = blk; > + } else { > + last_blk->next = blk; > + last_blk = blk; > + } > CodingStyle is off. > + /* Device name */ > + qemu_put_be64(f,(cur_sector << SECTOR_BITS) | BLK_MIG_FLAG_DEVICE_BLOCK); > + > + len = strlen(bs->device_name); > + qemu_put_byte(f, len); > + qemu_put_buffer(f, (uint8_t *)bs->device_name, len); > + > + qemu_put_buffer(f, tmp_buf, BLOCK_SIZE); > Would be good to do a simple check for an all zero block. That would help the initial transfer. Regards, Anthony Liguori