qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

Merge remote-tracking branch 'remotes/jnsnow/tags/bitmaps-pull-request' into staging

Pull request

# gpg: Signature made Mon 29 Oct 2018 21:24:08 GMT
# gpg: using RSA key 7DEF8106AAFC390E
# gpg: Good signature from "John Snow (John Huston) <jsnow@redhat.com>"
# Primary key fingerprint: FAEB 9711 A12C F475 812F 18F2 88A9 064D 1835 61EB
# Subkey fingerprint: F9B7 ABDB BCAC DF95 BE76 CBD0 7DEF 8106 AAFC 390E

* remotes/jnsnow/tags/bitmaps-pull-request:
iotests: 169: add cases for source vm resuming
iotests: improve 169
dirty-bitmaps: clean-up bitmaps loading and migration logic
bitmap: Update count after a merge
nbd: forbid use of frozen bitmaps
block/backup: prohibit backup from using in use bitmaps
block/dirty-bitmaps: prohibit enable/disable on locked/frozen bitmaps
block/dirty-bitmaps: allow clear on disabled bitmaps
block/dirty-bitmaps: fix merge permissions
block/dirty-bitmaps: add user_locked status checker
bloc/qcow2: drop dirty_bitmaps_loaded state variable
block/qcow2: improve error message in qcow2_inactivate
iotests: 169: drop deprecated 'autoload' parameter
qapi: add transaction support for x-block-dirty-bitmap-merge
blockdev: rename block-dirty-bitmap-clear transaction handlers
dirty-bitmap: make it possible to restore bitmap after merge
dirty-bitmap: rename bdrv_undo_clear_dirty_bitmap
dirty-bitmap: switch assert-fails to errors in bdrv_merge_dirty_bitmap
blockdev-backup: add bitmap argument

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

+343 -137
+7 -4
block.c
··· 4403 4403 uint64_t perm, shared_perm; 4404 4404 Error *local_err = NULL; 4405 4405 int ret; 4406 + BdrvDirtyBitmap *bm; 4406 4407 4407 4408 if (!bs->drv) { 4408 4409 return; ··· 4450 4451 error_propagate(errp, local_err); 4451 4452 return; 4452 4453 } 4454 + } 4455 + 4456 + for (bm = bdrv_dirty_bitmap_next(bs, NULL); bm; 4457 + bm = bdrv_dirty_bitmap_next(bs, bm)) 4458 + { 4459 + bdrv_dirty_bitmap_set_migration(bm, false); 4453 4460 } 4454 4461 4455 4462 ret = refresh_total_sectors(bs, bs->total_sectors); ··· 4565 4572 return ret; 4566 4573 } 4567 4574 } 4568 - 4569 - /* At this point persistent bitmaps should be already stored by the format 4570 - * driver */ 4571 - bdrv_release_persistent_dirty_bitmaps(bs); 4572 4575 4573 4576 return 0; 4574 4577 }
+49 -30
block/dirty-bitmap.c
··· 55 55 and this bitmap must remain unchanged while 56 56 this flag is set. */ 57 57 bool persistent; /* bitmap must be saved to owner disk image */ 58 + bool migration; /* Bitmap is selected for migration, it should 59 + not be stored on the next inactivation 60 + (persistent flag doesn't matter until next 61 + invalidation).*/ 58 62 QLIST_ENTRY(BdrvDirtyBitmap) list; 59 63 }; 60 64 ··· 174 178 bool bdrv_dirty_bitmap_frozen(BdrvDirtyBitmap *bitmap) 175 179 { 176 180 return bitmap->successor; 181 + } 182 + 183 + /* Both conditions disallow user-modification via QMP. */ 184 + bool bdrv_dirty_bitmap_user_locked(BdrvDirtyBitmap *bitmap) { 185 + return bdrv_dirty_bitmap_frozen(bitmap) || 186 + bdrv_dirty_bitmap_qmp_locked(bitmap); 177 187 } 178 188 179 189 void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked) ··· 314 324 return NULL; 315 325 } 316 326 317 - if (!hbitmap_merge(parent->bitmap, successor->bitmap)) { 327 + if (!hbitmap_merge(parent->bitmap, successor->bitmap, parent->bitmap)) { 318 328 error_setg(errp, "Merging of parent and successor bitmap failed"); 319 329 return NULL; 320 330 } ··· 384 394 } 385 395 386 396 /** 387 - * Release all persistent dirty bitmaps attached to a BDS (for use in 388 - * bdrv_inactivate_recurse()). 389 - * There must not be any frozen bitmaps attached. 390 - * This function does not remove persistent bitmaps from the storage. 391 - * Called with BQL taken. 392 - */ 393 - void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs) 394 - { 395 - BdrvDirtyBitmap *bm, *next; 396 - 397 - bdrv_dirty_bitmaps_lock(bs); 398 - QLIST_FOREACH_SAFE(bm, &bs->dirty_bitmaps, list, next) { 399 - if (bdrv_dirty_bitmap_get_persistance(bm)) { 400 - bdrv_release_dirty_bitmap_locked(bm); 401 - } 402 - } 403 - bdrv_dirty_bitmaps_unlock(bs); 404 - } 405 - 406 - /** 407 397 * Remove persistent dirty bitmap from the storage if it exists. 408 398 * Absence of bitmap is not an error, because we have the following scenario: 409 399 * BdrvDirtyBitmap can have .persistent = true but not yet saved and have no ··· 619 609 620 610 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out) 621 611 { 622 - assert(bdrv_dirty_bitmap_enabled(bitmap)); 623 612 assert(!bdrv_dirty_bitmap_readonly(bitmap)); 624 613 bdrv_dirty_bitmap_lock(bitmap); 625 614 if (!out) { ··· 633 622 bdrv_dirty_bitmap_unlock(bitmap); 634 623 } 635 624 636 - void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in) 625 + void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup) 637 626 { 638 627 HBitmap *tmp = bitmap->bitmap; 639 628 assert(bdrv_dirty_bitmap_enabled(bitmap)); 640 629 assert(!bdrv_dirty_bitmap_readonly(bitmap)); 641 - bitmap->bitmap = in; 630 + bitmap->bitmap = backup; 642 631 hbitmap_free(tmp); 643 632 } 644 633 ··· 756 745 qemu_mutex_unlock(bitmap->mutex); 757 746 } 758 747 748 + /* Called with BQL taken. */ 749 + void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migration) 750 + { 751 + qemu_mutex_lock(bitmap->mutex); 752 + bitmap->migration = migration; 753 + qemu_mutex_unlock(bitmap->mutex); 754 + } 755 + 759 756 bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap) 760 757 { 761 - return bitmap->persistent; 758 + return bitmap->persistent && !bitmap->migration; 762 759 } 763 760 764 761 bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs) 765 762 { 766 763 BdrvDirtyBitmap *bm; 767 764 QLIST_FOREACH(bm, &bs->dirty_bitmaps, list) { 768 - if (bm->persistent && !bm->readonly) { 765 + if (bm->persistent && !bm->readonly && !bm->migration) { 769 766 return true; 770 767 } 771 768 } ··· 791 788 } 792 789 793 790 void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src, 794 - Error **errp) 791 + HBitmap **backup, Error **errp) 795 792 { 793 + bool ret; 794 + 796 795 /* only bitmaps from one bds are supported */ 797 796 assert(dest->mutex == src->mutex); 798 797 799 798 qemu_mutex_lock(dest->mutex); 800 799 801 - assert(bdrv_dirty_bitmap_enabled(dest)); 802 - assert(!bdrv_dirty_bitmap_readonly(dest)); 800 + if (bdrv_dirty_bitmap_user_locked(dest)) { 801 + error_setg(errp, "Bitmap '%s' is currently in use by another" 802 + " operation and cannot be modified", dest->name); 803 + goto out; 804 + } 805 + 806 + if (bdrv_dirty_bitmap_readonly(dest)) { 807 + error_setg(errp, "Bitmap '%s' is readonly and cannot be modified", 808 + dest->name); 809 + goto out; 810 + } 803 811 804 - if (!hbitmap_merge(dest->bitmap, src->bitmap)) { 812 + if (!hbitmap_can_merge(dest->bitmap, src->bitmap)) { 805 813 error_setg(errp, "Bitmaps are incompatible and can't be merged"); 814 + goto out; 806 815 } 807 816 817 + if (backup) { 818 + *backup = dest->bitmap; 819 + dest->bitmap = hbitmap_alloc(dest->size, hbitmap_granularity(*backup)); 820 + ret = hbitmap_merge(*backup, src->bitmap, dest->bitmap); 821 + } else { 822 + ret = hbitmap_merge(dest->bitmap, src->bitmap, dest->bitmap); 823 + } 824 + assert(ret); 825 + 826 + out: 808 827 qemu_mutex_unlock(dest->mutex); 809 828 }
+16
block/qcow2-bitmap.c
··· 1418 1418 g_free(tb); 1419 1419 } 1420 1420 1421 + QSIMPLEQ_FOREACH(bm, bm_list, entry) { 1422 + /* For safety, we remove bitmap after storing. 1423 + * We may be here in two cases: 1424 + * 1. bdrv_close. It's ok to drop bitmap. 1425 + * 2. inactivation. It means migration without 'dirty-bitmaps' 1426 + * capability, so bitmaps are not marked with 1427 + * BdrvDirtyBitmap.migration flags. It's not bad to drop them too, 1428 + * and reload on invalidation. 1429 + */ 1430 + if (bm->dirty_bitmap == NULL) { 1431 + continue; 1432 + } 1433 + 1434 + bdrv_release_dirty_bitmap(bs, bm->dirty_bitmap); 1435 + } 1436 + 1421 1437 bitmap_list_free(bm_list); 1422 1438 return; 1423 1439
+66 -20
block/qcow2.c
··· 1153 1153 uint64_t ext_end; 1154 1154 uint64_t l1_vm_state_index; 1155 1155 bool update_header = false; 1156 - bool header_updated = false; 1157 1156 1158 1157 ret = bdrv_pread(bs->file, 0, &header, sizeof(header)); 1159 1158 if (ret < 0) { ··· 1492 1491 s->autoclear_features &= QCOW2_AUTOCLEAR_MASK; 1493 1492 } 1494 1493 1495 - if (s->dirty_bitmaps_loaded) { 1496 - /* It's some kind of reopen. There are no known cases where we need to 1497 - * reload bitmaps in such a situation, so it's safer to skip them. 1498 - * 1499 - * Moreover, if we have some readonly bitmaps and we are reopening for 1500 - * rw we should reopen bitmaps correspondingly. 1501 - */ 1502 - if (bdrv_has_readonly_bitmaps(bs) && 1503 - !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE)) 1504 - { 1505 - qcow2_reopen_bitmaps_rw_hint(bs, &header_updated, &local_err); 1506 - } 1507 - } else { 1508 - header_updated = qcow2_load_dirty_bitmaps(bs, &local_err); 1509 - s->dirty_bitmaps_loaded = true; 1494 + /* == Handle persistent dirty bitmaps == 1495 + * 1496 + * We want load dirty bitmaps in three cases: 1497 + * 1498 + * 1. Normal open of the disk in active mode, not related to invalidation 1499 + * after migration. 1500 + * 1501 + * 2. Invalidation of the target vm after pre-copy phase of migration, if 1502 + * bitmaps are _not_ migrating through migration channel, i.e. 1503 + * 'dirty-bitmaps' capability is disabled. 1504 + * 1505 + * 3. Invalidation of source vm after failed or canceled migration. 1506 + * This is a very interesting case. There are two possible types of 1507 + * bitmaps: 1508 + * 1509 + * A. Stored on inactivation and removed. They should be loaded from the 1510 + * image. 1511 + * 1512 + * B. Not stored: not-persistent bitmaps and bitmaps, migrated through 1513 + * the migration channel (with dirty-bitmaps capability). 1514 + * 1515 + * On the other hand, there are two possible sub-cases: 1516 + * 1517 + * 3.1 disk was changed by somebody else while were inactive. In this 1518 + * case all in-RAM dirty bitmaps (both persistent and not) are 1519 + * definitely invalid. And we don't have any method to determine 1520 + * this. 1521 + * 1522 + * Simple and safe thing is to just drop all the bitmaps of type B on 1523 + * inactivation. But in this case we lose bitmaps in valid 4.2 case. 1524 + * 1525 + * On the other hand, resuming source vm, if disk was already changed 1526 + * is a bad thing anyway: not only bitmaps, the whole vm state is 1527 + * out of sync with disk. 1528 + * 1529 + * This means, that user or management tool, who for some reason 1530 + * decided to resume source vm, after disk was already changed by 1531 + * target vm, should at least drop all dirty bitmaps by hand. 1532 + * 1533 + * So, we can ignore this case for now, but TODO: "generation" 1534 + * extension for qcow2, to determine, that image was changed after 1535 + * last inactivation. And if it is changed, we will drop (or at least 1536 + * mark as 'invalid' all the bitmaps of type B, both persistent 1537 + * and not). 1538 + * 1539 + * 3.2 disk was _not_ changed while were inactive. Bitmaps may be saved 1540 + * to disk ('dirty-bitmaps' capability disabled), or not saved 1541 + * ('dirty-bitmaps' capability enabled), but we don't need to care 1542 + * of: let's load bitmaps as always: stored bitmaps will be loaded, 1543 + * and not stored has flag IN_USE=1 in the image and will be skipped 1544 + * on loading. 1545 + * 1546 + * One remaining possible case when we don't want load bitmaps: 1547 + * 1548 + * 4. Open disk in inactive mode in target vm (bitmaps are migrating or 1549 + * will be loaded on invalidation, no needs try loading them before) 1550 + */ 1551 + 1552 + if (!(bdrv_get_flags(bs) & BDRV_O_INACTIVE)) { 1553 + /* It's case 1, 2 or 3.2. Or 3.1 which is BUG in management layer. */ 1554 + bool header_updated = qcow2_load_dirty_bitmaps(bs, &local_err); 1555 + 1556 + update_header = update_header && !header_updated; 1510 1557 } 1511 - update_header = update_header && !header_updated; 1512 1558 if (local_err != NULL) { 1513 1559 error_propagate(errp, local_err); 1514 1560 ret = -EINVAL; ··· 2123 2169 qcow2_store_persistent_dirty_bitmaps(bs, &local_err); 2124 2170 if (local_err != NULL) { 2125 2171 result = -EINVAL; 2126 - error_report_err(local_err); 2127 - error_report("Persistent bitmaps are lost for node '%s'", 2128 - bdrv_get_device_or_node_name(bs)); 2172 + error_reportf_err(local_err, "Lost persistent bitmaps during " 2173 + "inactivation of node '%s': ", 2174 + bdrv_get_device_or_node_name(bs)); 2129 2175 } 2130 2176 2131 2177 ret = qcow2_cache_flush(bs, s->l2_table_cache);
-1
block/qcow2.h
··· 300 300 uint32_t nb_bitmaps; 301 301 uint64_t bitmap_directory_size; 302 302 uint64_t bitmap_directory_offset; 303 - bool dirty_bitmaps_loaded; 304 303 305 304 int flags; 306 305 int qcow_version;
+89 -55
blockdev.c
··· 2010 2010 return; 2011 2011 } 2012 2012 2013 - if (bdrv_dirty_bitmap_frozen(state->bitmap)) { 2014 - error_setg(errp, "Cannot modify a frozen bitmap"); 2015 - return; 2016 - } else if (bdrv_dirty_bitmap_qmp_locked(state->bitmap)) { 2017 - error_setg(errp, "Cannot modify a locked bitmap"); 2018 - return; 2019 - } else if (!bdrv_dirty_bitmap_enabled(state->bitmap)) { 2020 - error_setg(errp, "Cannot clear a disabled bitmap"); 2013 + if (bdrv_dirty_bitmap_user_locked(state->bitmap)) { 2014 + error_setg(errp, "Cannot modify a bitmap in use by another operation"); 2021 2015 return; 2022 2016 } else if (bdrv_dirty_bitmap_readonly(state->bitmap)) { 2023 2017 error_setg(errp, "Cannot clear a readonly bitmap"); ··· 2027 2021 bdrv_clear_dirty_bitmap(state->bitmap, &state->backup); 2028 2022 } 2029 2023 2030 - static void block_dirty_bitmap_clear_abort(BlkActionState *common) 2024 + static void block_dirty_bitmap_restore(BlkActionState *common) 2031 2025 { 2032 2026 BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState, 2033 2027 common, common); 2034 2028 2035 2029 if (state->backup) { 2036 - bdrv_undo_clear_dirty_bitmap(state->bitmap, state->backup); 2030 + bdrv_restore_dirty_bitmap(state->bitmap, state->backup); 2037 2031 } 2038 2032 } 2039 2033 2040 - static void block_dirty_bitmap_clear_commit(BlkActionState *common) 2034 + static void block_dirty_bitmap_free_backup(BlkActionState *common) 2041 2035 { 2042 2036 BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState, 2043 2037 common, common); ··· 2065 2059 return; 2066 2060 } 2067 2061 2062 + if (bdrv_dirty_bitmap_user_locked(state->bitmap)) { 2063 + error_setg(errp, 2064 + "Bitmap '%s' is currently in use by another operation" 2065 + " and cannot be enabled", action->name); 2066 + return; 2067 + } 2068 + 2068 2069 state->was_enabled = bdrv_dirty_bitmap_enabled(state->bitmap); 2069 2070 bdrv_enable_dirty_bitmap(state->bitmap); 2070 2071 } ··· 2099 2100 return; 2100 2101 } 2101 2102 2103 + if (bdrv_dirty_bitmap_user_locked(state->bitmap)) { 2104 + error_setg(errp, 2105 + "Bitmap '%s' is currently in use by another operation" 2106 + " and cannot be disabled", action->name); 2107 + return; 2108 + } 2109 + 2102 2110 state->was_enabled = bdrv_dirty_bitmap_enabled(state->bitmap); 2103 2111 bdrv_disable_dirty_bitmap(state->bitmap); 2104 2112 } ··· 2113 2121 } 2114 2122 } 2115 2123 2124 + static void block_dirty_bitmap_merge_prepare(BlkActionState *common, 2125 + Error **errp) 2126 + { 2127 + BlockDirtyBitmapMerge *action; 2128 + BlockDirtyBitmapState *state = DO_UPCAST(BlockDirtyBitmapState, 2129 + common, common); 2130 + BdrvDirtyBitmap *merge_source; 2131 + 2132 + if (action_check_completion_mode(common, errp) < 0) { 2133 + return; 2134 + } 2135 + 2136 + action = common->action->u.x_block_dirty_bitmap_merge.data; 2137 + state->bitmap = block_dirty_bitmap_lookup(action->node, 2138 + action->dst_name, 2139 + &state->bs, 2140 + errp); 2141 + if (!state->bitmap) { 2142 + return; 2143 + } 2144 + 2145 + merge_source = bdrv_find_dirty_bitmap(state->bs, action->src_name); 2146 + if (!merge_source) { 2147 + return; 2148 + } 2149 + 2150 + bdrv_merge_dirty_bitmap(state->bitmap, merge_source, &state->backup, errp); 2151 + } 2152 + 2116 2153 static void abort_prepare(BlkActionState *common, Error **errp) 2117 2154 { 2118 2155 error_setg(errp, "Transaction aborted using Abort action"); ··· 2171 2208 [TRANSACTION_ACTION_KIND_BLOCK_DIRTY_BITMAP_CLEAR] = { 2172 2209 .instance_size = sizeof(BlockDirtyBitmapState), 2173 2210 .prepare = block_dirty_bitmap_clear_prepare, 2174 - .commit = block_dirty_bitmap_clear_commit, 2175 - .abort = block_dirty_bitmap_clear_abort, 2211 + .commit = block_dirty_bitmap_free_backup, 2212 + .abort = block_dirty_bitmap_restore, 2176 2213 }, 2177 2214 [TRANSACTION_ACTION_KIND_X_BLOCK_DIRTY_BITMAP_ENABLE] = { 2178 2215 .instance_size = sizeof(BlockDirtyBitmapState), ··· 2183 2220 .instance_size = sizeof(BlockDirtyBitmapState), 2184 2221 .prepare = block_dirty_bitmap_disable_prepare, 2185 2222 .abort = block_dirty_bitmap_disable_abort, 2223 + }, 2224 + [TRANSACTION_ACTION_KIND_X_BLOCK_DIRTY_BITMAP_MERGE] = { 2225 + .instance_size = sizeof(BlockDirtyBitmapState), 2226 + .prepare = block_dirty_bitmap_merge_prepare, 2227 + .commit = block_dirty_bitmap_free_backup, 2228 + .abort = block_dirty_bitmap_restore, 2186 2229 }, 2187 2230 /* Where are transactions for MIRROR, COMMIT and STREAM? 2188 2231 * Although these blockjobs use transaction callbacks like the backup job, ··· 2848 2891 return; 2849 2892 } 2850 2893 2851 - if (bdrv_dirty_bitmap_frozen(bitmap)) { 2852 - error_setg(errp, 2853 - "Bitmap '%s' is currently frozen and cannot be removed", 2854 - name); 2855 - return; 2856 - } else if (bdrv_dirty_bitmap_qmp_locked(bitmap)) { 2894 + if (bdrv_dirty_bitmap_user_locked(bitmap)) { 2857 2895 error_setg(errp, 2858 - "Bitmap '%s' is currently locked and cannot be removed", 2859 - name); 2896 + "Bitmap '%s' is currently in use by another operation and" 2897 + " cannot be removed", name); 2860 2898 return; 2861 2899 } 2862 2900 ··· 2886 2924 return; 2887 2925 } 2888 2926 2889 - if (bdrv_dirty_bitmap_frozen(bitmap)) { 2890 - error_setg(errp, 2891 - "Bitmap '%s' is currently frozen and cannot be modified", 2892 - name); 2893 - return; 2894 - } else if (bdrv_dirty_bitmap_qmp_locked(bitmap)) { 2895 - error_setg(errp, 2896 - "Bitmap '%s' is currently locked and cannot be modified", 2897 - name); 2898 - return; 2899 - } else if (!bdrv_dirty_bitmap_enabled(bitmap)) { 2927 + if (bdrv_dirty_bitmap_user_locked(bitmap)) { 2900 2928 error_setg(errp, 2901 - "Bitmap '%s' is currently disabled and cannot be cleared", 2902 - name); 2929 + "Bitmap '%s' is currently in use by another operation" 2930 + " and cannot be cleared", name); 2903 2931 return; 2904 2932 } else if (bdrv_dirty_bitmap_readonly(bitmap)) { 2905 2933 error_setg(errp, "Bitmap '%s' is readonly and cannot be cleared", name); ··· 2920 2948 return; 2921 2949 } 2922 2950 2923 - if (bdrv_dirty_bitmap_frozen(bitmap)) { 2951 + if (bdrv_dirty_bitmap_user_locked(bitmap)) { 2924 2952 error_setg(errp, 2925 - "Bitmap '%s' is currently frozen and cannot be enabled", 2926 - name); 2953 + "Bitmap '%s' is currently in use by another operation" 2954 + " and cannot be enabled", name); 2927 2955 return; 2928 2956 } 2929 2957 ··· 2941 2969 return; 2942 2970 } 2943 2971 2944 - if (bdrv_dirty_bitmap_frozen(bitmap)) { 2972 + if (bdrv_dirty_bitmap_user_locked(bitmap)) { 2945 2973 error_setg(errp, 2946 - "Bitmap '%s' is currently frozen and cannot be disabled", 2947 - name); 2974 + "Bitmap '%s' is currently in use by another operation" 2975 + " and cannot be disabled", name); 2948 2976 return; 2949 2977 } 2950 2978 ··· 2962 2990 return; 2963 2991 } 2964 2992 2965 - if (bdrv_dirty_bitmap_frozen(dst)) { 2966 - error_setg(errp, "Bitmap '%s' is frozen and cannot be modified", 2967 - dst_name); 2968 - return; 2969 - } else if (bdrv_dirty_bitmap_readonly(dst)) { 2970 - error_setg(errp, "Bitmap '%s' is readonly and cannot be modified", 2971 - dst_name); 2972 - return; 2973 - } 2974 - 2975 2993 src = bdrv_find_dirty_bitmap(bs, src_name); 2976 2994 if (!src) { 2977 2995 error_setg(errp, "Dirty bitmap '%s' not found", src_name); 2978 2996 return; 2979 2997 } 2980 2998 2981 - bdrv_merge_dirty_bitmap(dst, src, errp); 2999 + bdrv_merge_dirty_bitmap(dst, src, NULL, errp); 2982 3000 } 2983 3001 2984 3002 BlockDirtyBitmapSha256 *qmp_x_debug_block_dirty_bitmap_sha256(const char *node, ··· 3495 3513 bdrv_unref(target_bs); 3496 3514 goto out; 3497 3515 } 3498 - if (bdrv_dirty_bitmap_qmp_locked(bmap)) { 3516 + if (bdrv_dirty_bitmap_user_locked(bmap)) { 3499 3517 error_setg(errp, 3500 - "Bitmap '%s' is currently locked and cannot be used for " 3501 - "backup", backup->bitmap); 3518 + "Bitmap '%s' is currently in use by another operation" 3519 + " and cannot be used for backup", backup->bitmap); 3502 3520 goto out; 3503 3521 } 3504 3522 } ··· 3545 3563 BlockDriverState *bs; 3546 3564 BlockDriverState *target_bs; 3547 3565 Error *local_err = NULL; 3566 + BdrvDirtyBitmap *bmap = NULL; 3548 3567 AioContext *aio_context; 3549 3568 BlockJob *job = NULL; 3550 3569 int job_flags = JOB_DEFAULT; ··· 3595 3614 goto out; 3596 3615 } 3597 3616 } 3617 + 3618 + if (backup->has_bitmap) { 3619 + bmap = bdrv_find_dirty_bitmap(bs, backup->bitmap); 3620 + if (!bmap) { 3621 + error_setg(errp, "Bitmap '%s' could not be found", backup->bitmap); 3622 + goto out; 3623 + } 3624 + if (bdrv_dirty_bitmap_user_locked(bmap)) { 3625 + error_setg(errp, 3626 + "Bitmap '%s' is currently in use by another operation" 3627 + " and cannot be used for backup", backup->bitmap); 3628 + goto out; 3629 + } 3630 + } 3631 + 3598 3632 if (!backup->auto_finalize) { 3599 3633 job_flags |= JOB_MANUAL_FINALIZE; 3600 3634 } ··· 3602 3636 job_flags |= JOB_MANUAL_DISMISS; 3603 3637 } 3604 3638 job = backup_job_create(backup->job_id, bs, target_bs, backup->speed, 3605 - backup->sync, NULL, backup->compress, 3639 + backup->sync, bmap, backup->compress, 3606 3640 backup->on_source_error, backup->on_target_error, 3607 3641 job_flags, NULL, NULL, txn, &local_err); 3608 3642 if (local_err != NULL) {
+1 -1
include/block/block_int.h
··· 1155 1155 void bdrv_set_dirty(BlockDriverState *bs, int64_t offset, int64_t bytes); 1156 1156 1157 1157 void bdrv_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap **out); 1158 - void bdrv_undo_clear_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *in); 1158 + void bdrv_restore_dirty_bitmap(BdrvDirtyBitmap *bitmap, HBitmap *backup); 1159 1159 1160 1160 void bdrv_inc_in_flight(BlockDriverState *bs); 1161 1161 void bdrv_dec_in_flight(BlockDriverState *bs);
+3 -2
include/block/dirty-bitmap.h
··· 26 26 const char *name); 27 27 void bdrv_release_dirty_bitmap(BlockDriverState *bs, BdrvDirtyBitmap *bitmap); 28 28 void bdrv_release_named_dirty_bitmaps(BlockDriverState *bs); 29 - void bdrv_release_persistent_dirty_bitmaps(BlockDriverState *bs); 30 29 void bdrv_remove_persistent_dirty_bitmap(BlockDriverState *bs, 31 30 const char *name, 32 31 Error **errp); ··· 71 70 bool persistent); 72 71 void bdrv_dirty_bitmap_set_qmp_locked(BdrvDirtyBitmap *bitmap, bool qmp_locked); 73 72 void bdrv_merge_dirty_bitmap(BdrvDirtyBitmap *dest, const BdrvDirtyBitmap *src, 74 - Error **errp); 73 + HBitmap **backup, Error **errp); 74 + void bdrv_dirty_bitmap_set_migration(BdrvDirtyBitmap *bitmap, bool migration); 75 75 76 76 /* Functions that require manual locking. */ 77 77 void bdrv_dirty_bitmap_lock(BdrvDirtyBitmap *bitmap); ··· 94 94 bool bdrv_dirty_bitmap_get_autoload(const BdrvDirtyBitmap *bitmap); 95 95 bool bdrv_dirty_bitmap_get_persistance(BdrvDirtyBitmap *bitmap); 96 96 bool bdrv_dirty_bitmap_qmp_locked(BdrvDirtyBitmap *bitmap); 97 + bool bdrv_dirty_bitmap_user_locked(BdrvDirtyBitmap *bitmap); 97 98 bool bdrv_has_changed_persistent_bitmaps(BlockDriverState *bs); 98 99 BdrvDirtyBitmap *bdrv_dirty_bitmap_next(BlockDriverState *bs, 99 100 BdrvDirtyBitmap *bitmap);
+15 -8
include/qemu/hbitmap.h
··· 73 73 74 74 /** 75 75 * hbitmap_merge: 76 - * @a: The bitmap to store the result in. 77 - * @b: The bitmap to merge into @a. 78 - * @return true if the merge was successful, 79 - * false if it was not attempted. 76 + * 77 + * Store result of merging @a and @b into @result. 78 + * @result is allowed to be equal to @a or @b. 79 + * 80 + * Return true if the merge was successful, 81 + * false if it was not attempted. 82 + */ 83 + bool hbitmap_merge(const HBitmap *a, const HBitmap *b, HBitmap *result); 84 + 85 + /** 86 + * hbitmap_can_merge: 87 + * 88 + * hbitmap_can_merge(a, b) && hbitmap_can_merge(a, result) is sufficient and 89 + * necessary for hbitmap_merge will not fail. 80 90 * 81 - * Merge two bitmaps together. 82 - * A := A (BITOR) B. 83 - * B is left unmodified. 84 91 */ 85 - bool hbitmap_merge(HBitmap *a, const HBitmap *b); 92 + bool hbitmap_can_merge(const HBitmap *a, const HBitmap *b); 86 93 87 94 /** 88 95 * hbitmap_empty:
+6 -6
migration/block-dirty-bitmap.c
··· 301 301 goto fail; 302 302 } 303 303 304 - if (bdrv_dirty_bitmap_frozen(bitmap)) { 305 - error_report("Can't migrate frozen dirty bitmap: '%s", 304 + if (bdrv_dirty_bitmap_user_locked(bitmap)) { 305 + error_report("Can't migrate a bitmap that is in use by another operation: '%s'", 306 306 bdrv_dirty_bitmap_name(bitmap)); 307 307 goto fail; 308 308 } 309 309 310 - if (bdrv_dirty_bitmap_qmp_locked(bitmap)) { 311 - error_report("Can't migrate locked dirty bitmap: '%s", 310 + if (bdrv_dirty_bitmap_readonly(bitmap)) { 311 + error_report("Can't migrate read-only dirty bitmap: '%s", 312 312 bdrv_dirty_bitmap_name(bitmap)); 313 313 goto fail; 314 314 } ··· 335 335 } 336 336 } 337 337 338 - /* unset persistance here, to not roll back it */ 338 + /* unset migration flags here, to not roll back it */ 339 339 QSIMPLEQ_FOREACH(dbms, &dirty_bitmap_mig_state.dbms_list, entry) { 340 - bdrv_dirty_bitmap_set_persistance(dbms->bitmap, false); 340 + bdrv_dirty_bitmap_set_migration(dbms->bitmap, true); 341 341 } 342 342 343 343 if (QSIMPLEQ_EMPTY(&dirty_bitmap_mig_state.dbms_list)) {
+2 -2
nbd/server.c
··· 2456 2456 return; 2457 2457 } 2458 2458 2459 - if (bdrv_dirty_bitmap_qmp_locked(bm)) { 2460 - error_setg(errp, "Bitmap '%s' is locked", bitmap); 2459 + if (bdrv_dirty_bitmap_user_locked(bm)) { 2460 + error_setg(errp, "Bitmap '%s' is in use", bitmap); 2461 2461 return; 2462 2462 } 2463 2463
+6 -1
qapi/block-core.json
··· 1316 1316 # @speed: the maximum speed, in bytes per second. The default is 0, 1317 1317 # for unlimited. 1318 1318 # 1319 + # @bitmap: the name of dirty bitmap if sync is "incremental". 1320 + # Must be present if sync is "incremental", must NOT be present 1321 + # otherwise. (Since 3.1) 1322 + # 1319 1323 # @compress: true to compress data, if the target format supports it. 1320 1324 # (default: false) (since 2.8) 1321 1325 # ··· 1348 1352 ## 1349 1353 { 'struct': 'BlockdevBackup', 1350 1354 'data': { '*job-id': 'str', 'device': 'str', 'target': 'str', 1351 - 'sync': 'MirrorSyncMode', '*speed': 'int', '*compress': 'bool', 1355 + 'sync': 'MirrorSyncMode', '*speed': 'int', 1356 + '*bitmap': 'str', '*compress': 'bool', 1352 1357 '*on-source-error': 'BlockdevOnError', 1353 1358 '*on-target-error': 'BlockdevOnError', 1354 1359 '*auto-finalize': 'bool', '*auto-dismiss': 'bool' } }
+2
qapi/transaction.json
··· 48 48 # - @block-dirty-bitmap-clear: since 2.5 49 49 # - @x-block-dirty-bitmap-enable: since 3.0 50 50 # - @x-block-dirty-bitmap-disable: since 3.0 51 + # - @x-block-dirty-bitmap-merge: since 3.1 51 52 # - @blockdev-backup: since 2.3 52 53 # - @blockdev-snapshot: since 2.5 53 54 # - @blockdev-snapshot-internal-sync: since 1.7 ··· 63 64 'block-dirty-bitmap-clear': 'BlockDirtyBitmap', 64 65 'x-block-dirty-bitmap-enable': 'BlockDirtyBitmap', 65 66 'x-block-dirty-bitmap-disable': 'BlockDirtyBitmap', 67 + 'x-block-dirty-bitmap-merge': 'BlockDirtyBitmapMerge', 66 68 'blockdev-backup': 'BlockdevBackup', 67 69 'blockdev-snapshot': 'BlockdevSnapshot', 68 70 'blockdev-snapshot-internal-sync': 'BlockdevSnapshotInternal',
+68 -2
tests/qemu-iotests/169
··· 24 24 import itertools 25 25 import operator 26 26 import new 27 + import re 27 28 from iotests import qemu_img 28 29 29 30 ··· 58 59 'granularity': granularity} 59 60 if persistent: 60 61 params['persistent'] = True 61 - params['autoload'] = True 62 62 63 63 result = vm.qmp('block-dirty-bitmap-add', **params) 64 64 self.assert_qmp(result, 'return', {}); ··· 77 77 self.assert_qmp(result, 'error/desc', 78 78 "Dirty bitmap 'bitmap0' not found"); 79 79 80 + def do_test_migration_resume_source(self, persistent, migrate_bitmaps): 81 + granularity = 512 82 + 83 + # regions = ((start, count), ...) 84 + regions = ((0, 0x10000), 85 + (0xf0000, 0x10000), 86 + (0xa0201, 0x1000)) 87 + 88 + mig_caps = [{'capability': 'events', 'state': True}] 89 + if migrate_bitmaps: 90 + mig_caps.append({'capability': 'dirty-bitmaps', 'state': True}) 91 + 92 + result = self.vm_a.qmp('migrate-set-capabilities', 93 + capabilities=mig_caps) 94 + self.assert_qmp(result, 'return', {}) 95 + 96 + self.add_bitmap(self.vm_a, granularity, persistent) 97 + for r in regions: 98 + self.vm_a.hmp_qemu_io('drive0', 'write %d %d' % r) 99 + sha256 = self.get_bitmap_hash(self.vm_a) 100 + 101 + result = self.vm_a.qmp('migrate', uri=mig_cmd) 102 + while True: 103 + event = self.vm_a.event_wait('MIGRATION') 104 + if event['data']['status'] == 'completed': 105 + break 106 + 107 + # test that bitmap is still here 108 + removed = (not migrate_bitmaps) and persistent 109 + self.check_bitmap(self.vm_a, False if removed else sha256) 110 + 111 + self.vm_a.qmp('cont') 112 + 113 + # test that bitmap is still here after invalidation 114 + self.check_bitmap(self.vm_a, sha256) 115 + 116 + # shutdown and check that invalidation didn't fail 117 + self.vm_a.shutdown() 118 + 119 + # catch 'Could not reopen qcow2 layer: Bitmap already exists' 120 + # possible error 121 + log = self.vm_a.get_log() 122 + log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) 123 + log = re.sub(r'^(wrote .* bytes at offset .*\n.*KiB.*ops.*sec.*\n){3}', 124 + '', log) 125 + log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) 126 + self.assertEqual(log, '') 127 + 128 + # test that bitmap is still persistent 129 + self.vm_a.launch() 130 + self.check_bitmap(self.vm_a, sha256 if persistent else False) 131 + 80 132 def do_test_migration(self, persistent, migrate_bitmaps, online, 81 133 shared_storage): 82 134 granularity = 512 ··· 134 186 135 187 if should_migrate: 136 188 self.vm_b.shutdown() 189 + 190 + # catch 'Could not reopen qcow2 layer: Bitmap already exists' 191 + # possible error 192 + log = self.vm_b.get_log() 193 + log = re.sub(r'^\[I \d+\.\d+\] OPENED\n', '', log) 194 + log = re.sub(r'\[I \+\d+\.\d+\] CLOSED\n?$', '', log) 195 + self.assertEqual(log, '') 196 + 137 197 # recreate vm_b, as we don't want -incoming option (this will lead 138 198 # to "cat" process left alive after test finish) 139 199 self.vm_b = iotests.VM(path_suffix='b') ··· 144 204 145 205 def inject_test_case(klass, name, method, *args, **kwargs): 146 206 mc = operator.methodcaller(method, *args, **kwargs) 147 - setattr(klass, 'test_' + name, new.instancemethod(mc, None, klass)) 207 + setattr(klass, 'test_' + method + name, new.instancemethod(mc, None, klass)) 148 208 149 209 for cmb in list(itertools.product((True, False), repeat=4)): 150 210 name = ('_' if cmb[0] else '_not_') + 'persistent_' ··· 155 215 inject_test_case(TestDirtyBitmapMigration, name, 'do_test_migration', 156 216 *list(cmb)) 157 217 218 + for cmb in list(itertools.product((True, False), repeat=2)): 219 + name = ('_' if cmb[0] else '_not_') + 'persistent_' 220 + name += ('_' if cmb[1] else '_not_') + 'migbitmap' 221 + 222 + inject_test_case(TestDirtyBitmapMigration, name, 223 + 'do_test_migration_resume_source', *list(cmb)) 158 224 159 225 if __name__ == '__main__': 160 226 iotests.main(supported_fmts=['qcow2'])
+2 -2
tests/qemu-iotests/169.out
··· 1 - ................ 1 + .................... 2 2 ---------------------------------------------------------------------- 3 - Ran 16 tests 3 + Ran 20 tests 4 4 5 5 OK
+11 -3
util/hbitmap.c
··· 723 723 } 724 724 } 725 725 726 + bool hbitmap_can_merge(const HBitmap *a, const HBitmap *b) 727 + { 728 + return (a->size == b->size) && (a->granularity == b->granularity); 729 + } 726 730 727 731 /** 728 732 * Given HBitmaps A and B, let A := A (BITOR) B. ··· 731 735 * @return true if the merge was successful, 732 736 * false if it was not attempted. 733 737 */ 734 - bool hbitmap_merge(HBitmap *a, const HBitmap *b) 738 + bool hbitmap_merge(const HBitmap *a, const HBitmap *b, HBitmap *result) 735 739 { 736 740 int i; 737 741 uint64_t j; 738 742 739 - if ((a->size != b->size) || (a->granularity != b->granularity)) { 743 + if (!hbitmap_can_merge(a, b) || !hbitmap_can_merge(a, result)) { 740 744 return false; 741 745 } 746 + assert(hbitmap_can_merge(b, result)); 742 747 743 748 if (hbitmap_count(b) == 0) { 744 749 return true; ··· 750 755 */ 751 756 for (i = HBITMAP_LEVELS - 1; i >= 0; i--) { 752 757 for (j = 0; j < a->sizes[i]; j++) { 753 - a->levels[i][j] |= b->levels[i][j]; 758 + result->levels[i][j] = a->levels[i][j] | b->levels[i][j]; 754 759 } 755 760 } 761 + 762 + /* Recompute the dirty count */ 763 + result->count = hb_count_between(result, 0, result->size - 1); 756 764 757 765 return true; 758 766 }