target/hexagon: fix = vs. == mishap
[qemu/kevin.git] / block / monitor / bitmap-qmp-cmds.c
blob55f778f5af56b48d100c578dddc3e5035ddf2cdc
1 /*
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
10 * permission notice:
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
30 * THE SOFTWARE.
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"
41 /**
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,
54 const char *name,
55 BlockDriverState **pbs,
56 Error **errp)
58 BlockDriverState *bs;
59 BdrvDirtyBitmap *bitmap;
61 GLOBAL_STATE_CODE();
63 if (!node) {
64 error_setg(errp, "Node cannot be NULL");
65 return NULL;
67 if (!name) {
68 error_setg(errp, "Bitmap name cannot be NULL");
69 return NULL;
71 bs = bdrv_lookup_bs(node, node, NULL);
72 if (!bs) {
73 error_setg(errp, "Node '%s' not found", node);
74 return NULL;
77 bitmap = bdrv_find_dirty_bitmap(bs, name);
78 if (!bitmap) {
79 error_setg(errp, "Dirty bitmap '%s' not found", name);
80 return NULL;
83 if (pbs) {
84 *pbs = bs;
87 return bitmap;
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,
94 Error **errp)
96 BlockDriverState *bs;
97 BdrvDirtyBitmap *bitmap;
98 AioContext *aio_context;
100 if (!name || name[0] == '\0') {
101 error_setg(errp, "Bitmap name cannot be empty");
102 return;
105 bs = bdrv_lookup_bs(node, node, errp);
106 if (!bs) {
107 return;
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 "
116 "and at least 512");
117 goto out;
119 } else {
120 /* Default to cluster size, if available: */
121 granularity = bdrv_get_default_bitmap_granularity(bs);
124 if (!has_persistent) {
125 persistent = false;
128 if (!has_disabled) {
129 disabled = false;
132 if (persistent &&
133 !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp))
135 goto out;
138 bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp);
139 if (bitmap == NULL) {
140 goto out;
143 if (disabled) {
144 bdrv_disable_dirty_bitmap(bitmap);
147 bdrv_dirty_bitmap_set_persistence(bitmap, persistent);
149 out:
150 aio_context_release(aio_context);
153 BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
154 bool release,
155 BlockDriverState **bitmap_bs,
156 Error **errp)
158 BlockDriverState *bs;
159 BdrvDirtyBitmap *bitmap;
160 AioContext *aio_context;
162 GLOBAL_STATE_CODE();
164 bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
165 if (!bitmap || !bs) {
166 return NULL;
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,
173 errp)) {
174 aio_context_release(aio_context);
175 return NULL;
178 if (bdrv_dirty_bitmap_get_persistence(bitmap) &&
179 bdrv_remove_persistent_dirty_bitmap(bs, name, errp) < 0)
181 aio_context_release(aio_context);
182 return NULL;
185 if (release) {
186 bdrv_release_dirty_bitmap(bitmap);
189 if (bitmap_bs) {
190 *bitmap_bs = bs;
193 aio_context_release(aio_context);
194 return release ? NULL : bitmap;
197 void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
198 Error **errp)
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,
208 Error **errp)
210 BdrvDirtyBitmap *bitmap;
211 BlockDriverState *bs;
213 bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
214 if (!bitmap || !bs) {
215 return;
218 if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, errp)) {
219 return;
222 bdrv_clear_dirty_bitmap(bitmap, NULL);
225 void qmp_block_dirty_bitmap_enable(const char *node, const char *name,
226 Error **errp)
228 BlockDriverState *bs;
229 BdrvDirtyBitmap *bitmap;
231 bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
232 if (!bitmap) {
233 return;
236 if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
237 return;
240 bdrv_enable_dirty_bitmap(bitmap);
243 void qmp_block_dirty_bitmap_disable(const char *node, const char *name,
244 Error **errp)
246 BlockDriverState *bs;
247 BdrvDirtyBitmap *bitmap;
249 bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
250 if (!bitmap) {
251 return;
254 if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
255 return;
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;
270 GLOBAL_STATE_CODE();
272 dst = block_dirty_bitmap_lookup(node, target, &bs, errp);
273 if (!dst) {
274 return NULL;
277 for (lst = bms; lst; lst = lst->next) {
278 switch (lst->value->type) {
279 const char *name, *node;
280 case QTYPE_QSTRING:
281 name = lst->value->u.local;
282 src = bdrv_find_dirty_bitmap(bs, name);
283 if (!src) {
284 error_setg(errp, "Dirty bitmap '%s' not found", name);
285 goto fail;
287 break;
288 case QTYPE_QDICT:
289 node = lst->value->u.external.node;
290 name = lst->value->u.external.name;
291 src = block_dirty_bitmap_lookup(node, name, NULL, errp);
292 if (!src) {
293 goto fail;
295 break;
296 default:
297 abort();
300 /* We do backup only for first merge operation */
301 if (!bdrv_merge_dirty_bitmap(dst, src,
302 local_backup ? NULL : &local_backup,
303 errp))
305 goto fail;
309 if (backup) {
310 *backup = local_backup;
311 } else {
312 hbitmap_free(local_backup);
315 return dst;
317 fail:
318 if (local_backup) {
319 bdrv_restore_dirty_bitmap(dst, local_backup);
322 return NULL;
325 void qmp_block_dirty_bitmap_merge(const char *node, const char *target,
326 BlockDirtyBitmapOrStrList *bitmaps,
327 Error **errp)
329 block_dirty_bitmap_merge(node, target, bitmaps, NULL, errp);