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
;
60 error_setg(errp
, "Node cannot be NULL");
64 error_setg(errp
, "Bitmap name cannot be NULL");
67 bs
= bdrv_lookup_bs(node
, node
, NULL
);
69 error_setg(errp
, "Node '%s' not found", node
);
73 bitmap
= bdrv_find_dirty_bitmap(bs
, name
);
75 error_setg(errp
, "Dirty bitmap '%s' not found", name
);
86 void qmp_block_dirty_bitmap_add(const char *node
, const char *name
,
87 bool has_granularity
, uint32_t granularity
,
88 bool has_persistent
, bool persistent
,
89 bool has_disabled
, bool disabled
,
93 BdrvDirtyBitmap
*bitmap
;
94 AioContext
*aio_context
;
96 if (!name
|| name
[0] == '\0') {
97 error_setg(errp
, "Bitmap name cannot be empty");
101 bs
= bdrv_lookup_bs(node
, node
, errp
);
106 aio_context
= bdrv_get_aio_context(bs
);
107 aio_context_acquire(aio_context
);
109 if (has_granularity
) {
110 if (granularity
< 512 || !is_power_of_2(granularity
)) {
111 error_setg(errp
, "Granularity must be power of 2 "
116 /* Default to cluster size, if available: */
117 granularity
= bdrv_get_default_bitmap_granularity(bs
);
120 if (!has_persistent
) {
129 !bdrv_can_store_new_dirty_bitmap(bs
, name
, granularity
, errp
))
134 bitmap
= bdrv_create_dirty_bitmap(bs
, granularity
, name
, errp
);
135 if (bitmap
== NULL
) {
140 bdrv_disable_dirty_bitmap(bitmap
);
143 bdrv_dirty_bitmap_set_persistence(bitmap
, persistent
);
146 aio_context_release(aio_context
);
149 BdrvDirtyBitmap
*block_dirty_bitmap_remove(const char *node
, const char *name
,
151 BlockDriverState
**bitmap_bs
,
154 BlockDriverState
*bs
;
155 BdrvDirtyBitmap
*bitmap
;
156 AioContext
*aio_context
;
158 bitmap
= block_dirty_bitmap_lookup(node
, name
, &bs
, errp
);
159 if (!bitmap
|| !bs
) {
163 aio_context
= bdrv_get_aio_context(bs
);
164 aio_context_acquire(aio_context
);
166 if (bdrv_dirty_bitmap_check(bitmap
, BDRV_BITMAP_BUSY
| BDRV_BITMAP_RO
,
168 aio_context_release(aio_context
);
172 if (bdrv_dirty_bitmap_get_persistence(bitmap
) &&
173 bdrv_remove_persistent_dirty_bitmap(bs
, name
, errp
) < 0)
175 aio_context_release(aio_context
);
180 bdrv_release_dirty_bitmap(bitmap
);
187 aio_context_release(aio_context
);
188 return release
? NULL
: bitmap
;
191 void qmp_block_dirty_bitmap_remove(const char *node
, const char *name
,
194 block_dirty_bitmap_remove(node
, name
, true, NULL
, errp
);
198 * Completely clear a bitmap, for the purposes of synchronizing a bitmap
199 * immediately after a full backup operation.
201 void qmp_block_dirty_bitmap_clear(const char *node
, const char *name
,
204 BdrvDirtyBitmap
*bitmap
;
205 BlockDriverState
*bs
;
207 bitmap
= block_dirty_bitmap_lookup(node
, name
, &bs
, errp
);
208 if (!bitmap
|| !bs
) {
212 if (bdrv_dirty_bitmap_check(bitmap
, BDRV_BITMAP_DEFAULT
, errp
)) {
216 bdrv_clear_dirty_bitmap(bitmap
, NULL
);
219 void qmp_block_dirty_bitmap_enable(const char *node
, const char *name
,
222 BlockDriverState
*bs
;
223 BdrvDirtyBitmap
*bitmap
;
225 bitmap
= block_dirty_bitmap_lookup(node
, name
, &bs
, errp
);
230 if (bdrv_dirty_bitmap_check(bitmap
, BDRV_BITMAP_ALLOW_RO
, errp
)) {
234 bdrv_enable_dirty_bitmap(bitmap
);
237 void qmp_block_dirty_bitmap_disable(const char *node
, const char *name
,
240 BlockDriverState
*bs
;
241 BdrvDirtyBitmap
*bitmap
;
243 bitmap
= block_dirty_bitmap_lookup(node
, name
, &bs
, errp
);
248 if (bdrv_dirty_bitmap_check(bitmap
, BDRV_BITMAP_ALLOW_RO
, errp
)) {
252 bdrv_disable_dirty_bitmap(bitmap
);
255 BdrvDirtyBitmap
*block_dirty_bitmap_merge(const char *node
, const char *target
,
256 BlockDirtyBitmapMergeSourceList
*bms
,
257 HBitmap
**backup
, Error
**errp
)
259 BlockDriverState
*bs
;
260 BdrvDirtyBitmap
*dst
, *src
, *anon
;
261 BlockDirtyBitmapMergeSourceList
*lst
;
262 Error
*local_err
= NULL
;
264 dst
= block_dirty_bitmap_lookup(node
, target
, &bs
, errp
);
269 anon
= bdrv_create_dirty_bitmap(bs
, bdrv_dirty_bitmap_granularity(dst
),
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
);
288 node
= lst
->value
->u
.external
.node
;
289 name
= lst
->value
->u
.external
.name
;
290 src
= block_dirty_bitmap_lookup(node
, name
, NULL
, errp
);
300 bdrv_merge_dirty_bitmap(anon
, src
, NULL
, &local_err
);
302 error_propagate(errp
, local_err
);
308 /* Merge into dst; dst is unchanged on failure. */
309 bdrv_merge_dirty_bitmap(dst
, anon
, backup
, errp
);
312 bdrv_release_dirty_bitmap(anon
);
316 void qmp_block_dirty_bitmap_merge(const char *node
, const char *target
,
317 BlockDirtyBitmapMergeSourceList
*bitmaps
,
320 block_dirty_bitmap_merge(node
, target
, bitmaps
, NULL
, errp
);