2 * QEMU block dirty bitmap QMP commands
4 * Copyright (c) 2003-2008 Fabrice Bellard
6 * This work is licensed under the terms of the GNU GPL, version 2 or
7 * later. See the COPYING file in the top-level directory.
9 * This file incorporates work covered by the following copyright and
12 * Copyright (c) 2003-2008 Fabrice Bellard
14 * Permission is hereby granted, free of charge, to any person obtaining a copy
15 * of this software and associated documentation files (the "Software"), to deal
16 * in the Software without restriction, including without limitation the rights
17 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 * copies of the Software, and to permit persons to whom the Software is
19 * furnished to do so, subject to the following conditions:
21 * The above copyright notice and this permission notice shall be included in
22 * all copies or substantial portions of the Software.
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33 #include "qemu/osdep.h"
35 #include "block/block_int.h"
36 #include "qapi/qapi-commands-block.h"
37 #include "qapi/error.h"
40 * block_dirty_bitmap_lookup:
41 * Return a dirty bitmap (if present), after validating
42 * the node reference and bitmap names.
44 * @node: The name of the BDS node to search for bitmaps
45 * @name: The name of the bitmap to search for
46 * @pbs: Output pointer for BDS lookup, if desired. Can be NULL.
47 * @errp: Output pointer for error information. Can be NULL.
49 * @return: A bitmap object on success, or NULL on failure.
51 BdrvDirtyBitmap
*block_dirty_bitmap_lookup(const char *node
,
53 BlockDriverState
**pbs
,
57 BdrvDirtyBitmap
*bitmap
;
62 error_setg(errp
, "Node cannot be NULL");
66 error_setg(errp
, "Bitmap name cannot be NULL");
69 bs
= bdrv_lookup_bs(node
, node
, NULL
);
71 error_setg(errp
, "Node '%s' not found", node
);
75 bitmap
= bdrv_find_dirty_bitmap(bs
, name
);
77 error_setg(errp
, "Dirty bitmap '%s' not found", name
);
88 void qmp_block_dirty_bitmap_add(const char *node
, const char *name
,
89 bool has_granularity
, uint32_t granularity
,
90 bool has_persistent
, bool persistent
,
91 bool has_disabled
, bool disabled
,
95 BdrvDirtyBitmap
*bitmap
;
96 AioContext
*aio_context
;
98 if (!name
|| name
[0] == '\0') {
99 error_setg(errp
, "Bitmap name cannot be empty");
103 bs
= bdrv_lookup_bs(node
, node
, errp
);
108 aio_context
= bdrv_get_aio_context(bs
);
109 aio_context_acquire(aio_context
);
111 if (has_granularity
) {
112 if (granularity
< 512 || !is_power_of_2(granularity
)) {
113 error_setg(errp
, "Granularity must be power of 2 "
118 /* Default to cluster size, if available: */
119 granularity
= bdrv_get_default_bitmap_granularity(bs
);
122 if (!has_persistent
) {
131 !bdrv_can_store_new_dirty_bitmap(bs
, name
, granularity
, errp
))
136 bitmap
= bdrv_create_dirty_bitmap(bs
, granularity
, name
, errp
);
137 if (bitmap
== NULL
) {
142 bdrv_disable_dirty_bitmap(bitmap
);
145 bdrv_dirty_bitmap_set_persistence(bitmap
, persistent
);
148 aio_context_release(aio_context
);
151 BdrvDirtyBitmap
*block_dirty_bitmap_remove(const char *node
, const char *name
,
153 BlockDriverState
**bitmap_bs
,
156 BlockDriverState
*bs
;
157 BdrvDirtyBitmap
*bitmap
;
158 AioContext
*aio_context
;
162 bitmap
= block_dirty_bitmap_lookup(node
, name
, &bs
, errp
);
163 if (!bitmap
|| !bs
) {
167 aio_context
= bdrv_get_aio_context(bs
);
168 aio_context_acquire(aio_context
);
170 if (bdrv_dirty_bitmap_check(bitmap
, BDRV_BITMAP_BUSY
| BDRV_BITMAP_RO
,
172 aio_context_release(aio_context
);
176 if (bdrv_dirty_bitmap_get_persistence(bitmap
) &&
177 bdrv_remove_persistent_dirty_bitmap(bs
, name
, errp
) < 0)
179 aio_context_release(aio_context
);
184 bdrv_release_dirty_bitmap(bitmap
);
191 aio_context_release(aio_context
);
192 return release
? NULL
: bitmap
;
195 void qmp_block_dirty_bitmap_remove(const char *node
, const char *name
,
198 block_dirty_bitmap_remove(node
, name
, true, NULL
, errp
);
202 * Completely clear a bitmap, for the purposes of synchronizing a bitmap
203 * immediately after a full backup operation.
205 void qmp_block_dirty_bitmap_clear(const char *node
, const char *name
,
208 BdrvDirtyBitmap
*bitmap
;
209 BlockDriverState
*bs
;
211 bitmap
= block_dirty_bitmap_lookup(node
, name
, &bs
, errp
);
212 if (!bitmap
|| !bs
) {
216 if (bdrv_dirty_bitmap_check(bitmap
, BDRV_BITMAP_DEFAULT
, errp
)) {
220 bdrv_clear_dirty_bitmap(bitmap
, NULL
);
223 void qmp_block_dirty_bitmap_enable(const char *node
, const char *name
,
226 BlockDriverState
*bs
;
227 BdrvDirtyBitmap
*bitmap
;
229 bitmap
= block_dirty_bitmap_lookup(node
, name
, &bs
, errp
);
234 if (bdrv_dirty_bitmap_check(bitmap
, BDRV_BITMAP_ALLOW_RO
, errp
)) {
238 bdrv_enable_dirty_bitmap(bitmap
);
241 void qmp_block_dirty_bitmap_disable(const char *node
, const char *name
,
244 BlockDriverState
*bs
;
245 BdrvDirtyBitmap
*bitmap
;
247 bitmap
= block_dirty_bitmap_lookup(node
, name
, &bs
, errp
);
252 if (bdrv_dirty_bitmap_check(bitmap
, BDRV_BITMAP_ALLOW_RO
, errp
)) {
256 bdrv_disable_dirty_bitmap(bitmap
);
259 BdrvDirtyBitmap
*block_dirty_bitmap_merge(const char *node
, const char *target
,
260 BlockDirtyBitmapOrStrList
*bms
,
261 HBitmap
**backup
, Error
**errp
)
263 BlockDriverState
*bs
;
264 BdrvDirtyBitmap
*dst
, *src
;
265 BlockDirtyBitmapOrStrList
*lst
;
266 HBitmap
*local_backup
= NULL
;
270 dst
= block_dirty_bitmap_lookup(node
, target
, &bs
, errp
);
275 for (lst
= bms
; lst
; lst
= lst
->next
) {
276 switch (lst
->value
->type
) {
277 const char *name
, *node
;
279 name
= lst
->value
->u
.local
;
280 src
= bdrv_find_dirty_bitmap(bs
, name
);
282 error_setg(errp
, "Dirty bitmap '%s' not found", name
);
287 node
= lst
->value
->u
.external
.node
;
288 name
= lst
->value
->u
.external
.name
;
289 src
= block_dirty_bitmap_lookup(node
, name
, NULL
, errp
);
298 /* We do backup only for first merge operation */
299 if (!bdrv_merge_dirty_bitmap(dst
, src
,
300 local_backup
? NULL
: &local_backup
,
308 *backup
= local_backup
;
310 hbitmap_free(local_backup
);
317 bdrv_restore_dirty_bitmap(dst
, local_backup
);
323 void qmp_block_dirty_bitmap_merge(const char *node
, const char *target
,
324 BlockDirtyBitmapOrStrList
*bitmaps
,
327 block_dirty_bitmap_merge(node
, target
, bitmaps
, NULL
, errp
);