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-io.h"
36 #include "block/block_int.h"
37 #include "block/dirty-bitmap.h"
38 #include "qapi/qapi-commands-block.h"
39 #include "qapi/error.h"
42 * block_dirty_bitmap_lookup:
43 * Return a dirty bitmap (if present), after validating
44 * the node reference and bitmap names.
46 * @node: The name of the BDS node to search for bitmaps
47 * @name: The name of the bitmap to search for
48 * @pbs: Output pointer for BDS lookup, if desired. Can be NULL.
49 * @errp: Output pointer for error information. Can be NULL.
51 * @return: A bitmap object on success, or NULL on failure.
53 BdrvDirtyBitmap
*block_dirty_bitmap_lookup(const char *node
,
55 BlockDriverState
**pbs
,
59 BdrvDirtyBitmap
*bitmap
;
64 error_setg(errp
, "Node cannot be NULL");
68 error_setg(errp
, "Bitmap name cannot be NULL");
71 bs
= bdrv_lookup_bs(node
, node
, NULL
);
73 error_setg(errp
, "Node '%s' not found", node
);
77 bitmap
= bdrv_find_dirty_bitmap(bs
, name
);
79 error_setg(errp
, "Dirty bitmap '%s' not found", name
);
90 void qmp_block_dirty_bitmap_add(const char *node
, const char *name
,
91 bool has_granularity
, uint32_t granularity
,
92 bool has_persistent
, bool persistent
,
93 bool has_disabled
, bool disabled
,
97 BdrvDirtyBitmap
*bitmap
;
98 AioContext
*aio_context
;
100 if (!name
|| name
[0] == '\0') {
101 error_setg(errp
, "Bitmap name cannot be empty");
105 bs
= bdrv_lookup_bs(node
, node
, errp
);
110 aio_context
= bdrv_get_aio_context(bs
);
111 aio_context_acquire(aio_context
);
113 if (has_granularity
) {
114 if (granularity
< 512 || !is_power_of_2(granularity
)) {
115 error_setg(errp
, "Granularity must be power of 2 "
120 /* Default to cluster size, if available: */
121 granularity
= bdrv_get_default_bitmap_granularity(bs
);
124 if (!has_persistent
) {
133 !bdrv_can_store_new_dirty_bitmap(bs
, name
, granularity
, errp
))
138 bitmap
= bdrv_create_dirty_bitmap(bs
, granularity
, name
, errp
);
139 if (bitmap
== NULL
) {
144 bdrv_disable_dirty_bitmap(bitmap
);
147 bdrv_dirty_bitmap_set_persistence(bitmap
, persistent
);
150 aio_context_release(aio_context
);
153 BdrvDirtyBitmap
*block_dirty_bitmap_remove(const char *node
, const char *name
,
155 BlockDriverState
**bitmap_bs
,
158 BlockDriverState
*bs
;
159 BdrvDirtyBitmap
*bitmap
;
160 AioContext
*aio_context
;
164 bitmap
= block_dirty_bitmap_lookup(node
, name
, &bs
, errp
);
165 if (!bitmap
|| !bs
) {
169 aio_context
= bdrv_get_aio_context(bs
);
170 aio_context_acquire(aio_context
);
172 if (bdrv_dirty_bitmap_check(bitmap
, BDRV_BITMAP_BUSY
| BDRV_BITMAP_RO
,
174 aio_context_release(aio_context
);
178 if (bdrv_dirty_bitmap_get_persistence(bitmap
) &&
179 bdrv_remove_persistent_dirty_bitmap(bs
, name
, errp
) < 0)
181 aio_context_release(aio_context
);
186 bdrv_release_dirty_bitmap(bitmap
);
193 aio_context_release(aio_context
);
194 return release
? NULL
: bitmap
;
197 void qmp_block_dirty_bitmap_remove(const char *node
, const char *name
,
200 block_dirty_bitmap_remove(node
, name
, true, NULL
, errp
);
204 * Completely clear a bitmap, for the purposes of synchronizing a bitmap
205 * immediately after a full backup operation.
207 void qmp_block_dirty_bitmap_clear(const char *node
, const char *name
,
210 BdrvDirtyBitmap
*bitmap
;
211 BlockDriverState
*bs
;
213 bitmap
= block_dirty_bitmap_lookup(node
, name
, &bs
, errp
);
214 if (!bitmap
|| !bs
) {
218 if (bdrv_dirty_bitmap_check(bitmap
, BDRV_BITMAP_DEFAULT
, errp
)) {
222 bdrv_clear_dirty_bitmap(bitmap
, NULL
);
225 void qmp_block_dirty_bitmap_enable(const char *node
, const char *name
,
228 BlockDriverState
*bs
;
229 BdrvDirtyBitmap
*bitmap
;
231 bitmap
= block_dirty_bitmap_lookup(node
, name
, &bs
, errp
);
236 if (bdrv_dirty_bitmap_check(bitmap
, BDRV_BITMAP_ALLOW_RO
, errp
)) {
240 bdrv_enable_dirty_bitmap(bitmap
);
243 void qmp_block_dirty_bitmap_disable(const char *node
, const char *name
,
246 BlockDriverState
*bs
;
247 BdrvDirtyBitmap
*bitmap
;
249 bitmap
= block_dirty_bitmap_lookup(node
, name
, &bs
, errp
);
254 if (bdrv_dirty_bitmap_check(bitmap
, BDRV_BITMAP_ALLOW_RO
, errp
)) {
258 bdrv_disable_dirty_bitmap(bitmap
);
261 BdrvDirtyBitmap
*block_dirty_bitmap_merge(const char *node
, const char *target
,
262 BlockDirtyBitmapOrStrList
*bms
,
263 HBitmap
**backup
, Error
**errp
)
265 BlockDriverState
*bs
;
266 BdrvDirtyBitmap
*dst
, *src
;
267 BlockDirtyBitmapOrStrList
*lst
;
268 HBitmap
*local_backup
= NULL
;
272 dst
= block_dirty_bitmap_lookup(node
, target
, &bs
, errp
);
277 for (lst
= bms
; lst
; lst
= lst
->next
) {
278 switch (lst
->value
->type
) {
279 const char *name
, *node
;
281 name
= lst
->value
->u
.local
;
282 src
= bdrv_find_dirty_bitmap(bs
, name
);
284 error_setg(errp
, "Dirty bitmap '%s' not found", name
);
289 node
= lst
->value
->u
.external
.node
;
290 name
= lst
->value
->u
.external
.name
;
291 src
= block_dirty_bitmap_lookup(node
, name
, NULL
, errp
);
300 /* We do backup only for first merge operation */
301 if (!bdrv_merge_dirty_bitmap(dst
, src
,
302 local_backup
? NULL
: &local_backup
,
310 *backup
= local_backup
;
312 hbitmap_free(local_backup
);
319 bdrv_restore_dirty_bitmap(dst
, local_backup
);
325 void qmp_block_dirty_bitmap_merge(const char *node
, const char *target
,
326 BlockDirtyBitmapOrStrList
*bitmaps
,
329 block_dirty_bitmap_merge(node
, target
, bitmaps
, NULL
, errp
);