[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v9 10/13] migration: add postcopy migration of d
From: |
Fam Zheng |
Subject: |
Re: [Qemu-devel] [PATCH v9 10/13] migration: add postcopy migration of dirty bitmaps |
Date: |
Thu, 28 Dec 2017 14:14:57 +0800 |
User-agent: |
Mutt/1.9.1 (2017-09-22) |
On Wed, 12/20 18:49, Vladimir Sementsov-Ogievskiy wrote:
> Postcopy migration of dirty bitmaps. Only named dirty bitmaps,
> associated with root nodes and non-root named nodes are migrated.
>
> If destination qemu is already containing a dirty bitmap with the same name
> as a migrated bitmap (for the same node), then, if their granularities are
> the same the migration will be done, otherwise the error will be generated.
>
> If destination qemu doesn't contain such bitmap it will be created.
>
> Signed-off-by: Vladimir Sementsov-Ogievskiy <address@hidden>
Looks good in general, a few nits below.
> +static void send_bitmap_bits(QEMUFile *f, DirtyBitmapMigBitmapState *dbms,
> + uint64_t start_sector, uint32_t nr_sectors)
> +{
> + /* align for buffer_is_zero() */
> + uint64_t align = 4 * sizeof(long);
> + uint64_t unaligned_size =
> + bdrv_dirty_bitmap_serialization_size(
> + dbms->bitmap, start_sector << BDRV_SECTOR_BITS,
> + (uint64_t)nr_sectors << BDRV_SECTOR_BITS);
> + uint64_t buf_size = (unaligned_size + align - 1) & ~(align - 1);
QEMU_ALIGN_UP() ?
> + uint8_t *buf = g_malloc0(buf_size);
> + uint32_t flags = DIRTY_BITMAP_MIG_FLAG_BITS;
> +
> + bdrv_dirty_bitmap_serialize_part(
> + dbms->bitmap, buf, start_sector << BDRV_SECTOR_BITS,
> + (uint64_t)nr_sectors << BDRV_SECTOR_BITS);
> +
> + if (buffer_is_zero(buf, buf_size)) {
> + g_free(buf);
> + buf = NULL;
> + flags |= DIRTY_BITMAP_MIG_FLAG_ZEROES;
> + }
> +
> + trace_send_bitmap_bits(flags, start_sector, nr_sectors, buf_size);
> +
> + send_bitmap_header(f, dbms, flags);
> +
> + qemu_put_be64(f, start_sector);
> + qemu_put_be32(f, nr_sectors);
> +
> + /* if a block is zero we need to flush here since the network
> + * bandwidth is now a lot higher than the storage device bandwidth.
> + * thus if we queue zero blocks we slow down the migration. */
> + if (flags & DIRTY_BITMAP_MIG_FLAG_ZEROES) {
> + qemu_fflush(f);
> + } else {
> + qemu_put_be64(f, buf_size);
> + qemu_put_buffer(f, buf, buf_size);
> + }
> +
> + g_free(buf);
> +}
> +
<snip>
> +static void dirty_bitmap_save_pending(QEMUFile *f, void *opaque,
> + uint64_t max_size,
> + uint64_t *res_precopy_only,
> + uint64_t *res_compatible,
> + uint64_t *res_postcopy_only)
> +{
> + DirtyBitmapMigBitmapState *dbms;
> + uint64_t pending = 0;
> +
> + qemu_mutex_lock_iothread();
> +
> + QSIMPLEQ_FOREACH(dbms, &dirty_bitmap_mig_state.dbms_list, entry) {
> + uint64_t gran = bdrv_dirty_bitmap_granularity(dbms->bitmap);
> + uint64_t sectors = dbms->bulk_completed ? 0 :
> + dbms->total_sectors - dbms->cur_sector;
> +
> + pending += (sectors * BDRV_SECTOR_SIZE + gran - 1) / gran;
DIV_ROUND_UP()?
> + }
> +
> + qemu_mutex_unlock_iothread();
> +
> + trace_dirty_bitmap_save_pending(pending, max_size);
> +
> + *res_postcopy_only += pending;
> +}
<snip>
> +static int dirty_bitmap_load_header(QEMUFile *f, DirtyBitmapLoadState *s)
> +{
> + Error *local_err = NULL;
> + s->flags = qemu_get_bitmap_flags(f);
> + trace_dirty_bitmap_load_header(s->flags);
> +
> + if (s->flags & DIRTY_BITMAP_MIG_FLAG_DEVICE_NAME) {
> + if (!qemu_get_counted_string(f, s->node_name)) {
> + error_report("Unable to read node name string");
> + return -EINVAL;
> + }
> + s->bs = bdrv_lookup_bs(s->node_name, s->node_name, &local_err);
> + if (!s->bs) {
> + error_report_err(local_err);
> + return -EINVAL;
> + }
> + } else if (!s->bs) {
> + error_report("Error: block device name is not set");
> + return -EINVAL;
> + }
> +
> + if (s->flags & DIRTY_BITMAP_MIG_FLAG_BITMAP_NAME) {
> + if (!qemu_get_counted_string(f, s->bitmap_name)) {
> + error_report("Unable to read node name string");
s/node name/bitmap name/
> + return -EINVAL;
> + }
> + s->bitmap = bdrv_find_dirty_bitmap(s->bs, s->bitmap_name);
> +
> + /* bitmap may be NULL here, it wouldn't be an error if it is the
> + * first occurrence of the bitmap */
> + if (!s->bitmap && !(s->flags & DIRTY_BITMAP_MIG_FLAG_START)) {
> + error_report("Error: unknown dirty bitmap "
> + "'%s' for block device '%s'",
> + s->bitmap_name, s->node_name);
> + return -EINVAL;
> + }
> + } else if (!s->bitmap) {
> + error_report("Error: block device name is not set");
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
Fam
- [Qemu-devel] [PATCH v9 12/13] iotests: add dirty bitmap migration test, (continued)
- [Qemu-devel] [PATCH v9 12/13] iotests: add dirty bitmap migration test, Vladimir Sementsov-Ogievskiy, 2017/12/20
- [Qemu-devel] [PATCH v9 13/13] iotests: add dirty bitmap postcopy test, Vladimir Sementsov-Ogievskiy, 2017/12/20
- [Qemu-devel] [PATCH v9 02/13] block/dirty-bitmap: fix locking in bdrv_reclaim_dirty_bitmap, Vladimir Sementsov-Ogievskiy, 2017/12/20
- [Qemu-devel] [PATCH v9 01/13] block/dirty-bitmap: add bdrv_dirty_bitmap_enable_successor(), Vladimir Sementsov-Ogievskiy, 2017/12/20
- [Qemu-devel] [PATCH v9 10/13] migration: add postcopy migration of dirty bitmaps, Vladimir Sementsov-Ogievskiy, 2017/12/20
- Re: [Qemu-devel] [PATCH v9 10/13] migration: add postcopy migration of dirty bitmaps,
Fam Zheng <=