1bb4e58c6SEric Blake /*
2bb4e58c6SEric Blake * QEMU block dirty bitmap QMP commands
3bb4e58c6SEric Blake *
4bb4e58c6SEric Blake * Copyright (c) 2003-2008 Fabrice Bellard
5bb4e58c6SEric Blake *
6bb4e58c6SEric Blake * This work is licensed under the terms of the GNU GPL, version 2 or
7bb4e58c6SEric Blake * later. See the COPYING file in the top-level directory.
8bb4e58c6SEric Blake *
9bb4e58c6SEric Blake * This file incorporates work covered by the following copyright and
10bb4e58c6SEric Blake * permission notice:
11bb4e58c6SEric Blake *
12bb4e58c6SEric Blake * Copyright (c) 2003-2008 Fabrice Bellard
13bb4e58c6SEric Blake *
14bb4e58c6SEric Blake * Permission is hereby granted, free of charge, to any person obtaining a copy
15bb4e58c6SEric Blake * of this software and associated documentation files (the "Software"), to deal
16bb4e58c6SEric Blake * in the Software without restriction, including without limitation the rights
17bb4e58c6SEric Blake * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18bb4e58c6SEric Blake * copies of the Software, and to permit persons to whom the Software is
19bb4e58c6SEric Blake * furnished to do so, subject to the following conditions:
20bb4e58c6SEric Blake *
21bb4e58c6SEric Blake * The above copyright notice and this permission notice shall be included in
22bb4e58c6SEric Blake * all copies or substantial portions of the Software.
23bb4e58c6SEric Blake *
24bb4e58c6SEric Blake * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25bb4e58c6SEric Blake * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26bb4e58c6SEric Blake * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27bb4e58c6SEric Blake * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28bb4e58c6SEric Blake * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29bb4e58c6SEric Blake * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30bb4e58c6SEric Blake * THE SOFTWARE.
31bb4e58c6SEric Blake */
32bb4e58c6SEric Blake
33bb4e58c6SEric Blake #include "qemu/osdep.h"
34bb4e58c6SEric Blake
35e2c1c34fSMarkus Armbruster #include "block/block-io.h"
36bb4e58c6SEric Blake #include "block/block_int.h"
37e2c1c34fSMarkus Armbruster #include "block/dirty-bitmap.h"
38bb4e58c6SEric Blake #include "qapi/qapi-commands-block.h"
39bb4e58c6SEric Blake #include "qapi/error.h"
40bb4e58c6SEric Blake
41bb4e58c6SEric Blake /**
42bb4e58c6SEric Blake * block_dirty_bitmap_lookup:
43bb4e58c6SEric Blake * Return a dirty bitmap (if present), after validating
44bb4e58c6SEric Blake * the node reference and bitmap names.
45bb4e58c6SEric Blake *
46bb4e58c6SEric Blake * @node: The name of the BDS node to search for bitmaps
47bb4e58c6SEric Blake * @name: The name of the bitmap to search for
48bb4e58c6SEric Blake * @pbs: Output pointer for BDS lookup, if desired. Can be NULL.
49bb4e58c6SEric Blake * @errp: Output pointer for error information. Can be NULL.
50bb4e58c6SEric Blake *
51bb4e58c6SEric Blake * @return: A bitmap object on success, or NULL on failure.
52bb4e58c6SEric Blake */
block_dirty_bitmap_lookup(const char * node,const char * name,BlockDriverState ** pbs,Error ** errp)53bb4e58c6SEric Blake BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node,
54bb4e58c6SEric Blake const char *name,
55bb4e58c6SEric Blake BlockDriverState **pbs,
56bb4e58c6SEric Blake Error **errp)
57bb4e58c6SEric Blake {
58bb4e58c6SEric Blake BlockDriverState *bs;
59bb4e58c6SEric Blake BdrvDirtyBitmap *bitmap;
60bb4e58c6SEric Blake
61b4ad82aaSEmanuele Giuseppe Esposito GLOBAL_STATE_CODE();
62b4ad82aaSEmanuele Giuseppe Esposito
63bb4e58c6SEric Blake if (!node) {
64bb4e58c6SEric Blake error_setg(errp, "Node cannot be NULL");
65bb4e58c6SEric Blake return NULL;
66bb4e58c6SEric Blake }
67bb4e58c6SEric Blake if (!name) {
68bb4e58c6SEric Blake error_setg(errp, "Bitmap name cannot be NULL");
69bb4e58c6SEric Blake return NULL;
70bb4e58c6SEric Blake }
71bb4e58c6SEric Blake bs = bdrv_lookup_bs(node, node, NULL);
72bb4e58c6SEric Blake if (!bs) {
73bb4e58c6SEric Blake error_setg(errp, "Node '%s' not found", node);
74bb4e58c6SEric Blake return NULL;
75bb4e58c6SEric Blake }
76bb4e58c6SEric Blake
77bb4e58c6SEric Blake bitmap = bdrv_find_dirty_bitmap(bs, name);
78bb4e58c6SEric Blake if (!bitmap) {
79bb4e58c6SEric Blake error_setg(errp, "Dirty bitmap '%s' not found", name);
80bb4e58c6SEric Blake return NULL;
81bb4e58c6SEric Blake }
82bb4e58c6SEric Blake
83bb4e58c6SEric Blake if (pbs) {
84bb4e58c6SEric Blake *pbs = bs;
85bb4e58c6SEric Blake }
86bb4e58c6SEric Blake
87bb4e58c6SEric Blake return bitmap;
88bb4e58c6SEric Blake }
89bb4e58c6SEric Blake
qmp_block_dirty_bitmap_add(const char * node,const char * name,bool has_granularity,uint32_t granularity,bool has_persistent,bool persistent,bool has_disabled,bool disabled,Error ** errp)90bb4e58c6SEric Blake void qmp_block_dirty_bitmap_add(const char *node, const char *name,
91bb4e58c6SEric Blake bool has_granularity, uint32_t granularity,
92bb4e58c6SEric Blake bool has_persistent, bool persistent,
93bb4e58c6SEric Blake bool has_disabled, bool disabled,
94bb4e58c6SEric Blake Error **errp)
95bb4e58c6SEric Blake {
96bb4e58c6SEric Blake BlockDriverState *bs;
97bb4e58c6SEric Blake BdrvDirtyBitmap *bitmap;
98bb4e58c6SEric Blake
99bb4e58c6SEric Blake if (!name || name[0] == '\0') {
100bb4e58c6SEric Blake error_setg(errp, "Bitmap name cannot be empty");
101bb4e58c6SEric Blake return;
102bb4e58c6SEric Blake }
103bb4e58c6SEric Blake
104bb4e58c6SEric Blake bs = bdrv_lookup_bs(node, node, errp);
105bb4e58c6SEric Blake if (!bs) {
106bb4e58c6SEric Blake return;
107bb4e58c6SEric Blake }
108bb4e58c6SEric Blake
109bb4e58c6SEric Blake if (has_granularity) {
110bb4e58c6SEric Blake if (granularity < 512 || !is_power_of_2(granularity)) {
111bb4e58c6SEric Blake error_setg(errp, "Granularity must be power of 2 "
112bb4e58c6SEric Blake "and at least 512");
113*b49f4755SStefan Hajnoczi return;
114bb4e58c6SEric Blake }
115bb4e58c6SEric Blake } else {
116bb4e58c6SEric Blake /* Default to cluster size, if available: */
117bb4e58c6SEric Blake granularity = bdrv_get_default_bitmap_granularity(bs);
118bb4e58c6SEric Blake }
119bb4e58c6SEric Blake
120bb4e58c6SEric Blake if (!has_persistent) {
121bb4e58c6SEric Blake persistent = false;
122bb4e58c6SEric Blake }
123bb4e58c6SEric Blake
124bb4e58c6SEric Blake if (!has_disabled) {
125bb4e58c6SEric Blake disabled = false;
126bb4e58c6SEric Blake }
127bb4e58c6SEric Blake
128bb4e58c6SEric Blake if (persistent &&
129bb4e58c6SEric Blake !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp))
130bb4e58c6SEric Blake {
131*b49f4755SStefan Hajnoczi return;
132bb4e58c6SEric Blake }
133bb4e58c6SEric Blake
134bb4e58c6SEric Blake bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp);
135bb4e58c6SEric Blake if (bitmap == NULL) {
136*b49f4755SStefan Hajnoczi return;
137bb4e58c6SEric Blake }
138bb4e58c6SEric Blake
139bb4e58c6SEric Blake if (disabled) {
140bb4e58c6SEric Blake bdrv_disable_dirty_bitmap(bitmap);
141bb4e58c6SEric Blake }
142bb4e58c6SEric Blake
143bb4e58c6SEric Blake bdrv_dirty_bitmap_set_persistence(bitmap, persistent);
144bb4e58c6SEric Blake }
145bb4e58c6SEric Blake
block_dirty_bitmap_remove(const char * node,const char * name,bool release,BlockDriverState ** bitmap_bs,Error ** errp)146bb4e58c6SEric Blake BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name,
147bb4e58c6SEric Blake bool release,
148bb4e58c6SEric Blake BlockDriverState **bitmap_bs,
149bb4e58c6SEric Blake Error **errp)
150bb4e58c6SEric Blake {
151bb4e58c6SEric Blake BlockDriverState *bs;
152bb4e58c6SEric Blake BdrvDirtyBitmap *bitmap;
153bb4e58c6SEric Blake
154b4ad82aaSEmanuele Giuseppe Esposito GLOBAL_STATE_CODE();
155b4ad82aaSEmanuele Giuseppe Esposito
156bb4e58c6SEric Blake bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
157bb4e58c6SEric Blake if (!bitmap || !bs) {
158bb4e58c6SEric Blake return NULL;
159bb4e58c6SEric Blake }
160bb4e58c6SEric Blake
161bb4e58c6SEric Blake if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY | BDRV_BITMAP_RO,
162bb4e58c6SEric Blake errp)) {
163bb4e58c6SEric Blake return NULL;
164bb4e58c6SEric Blake }
165bb4e58c6SEric Blake
166bb4e58c6SEric Blake if (bdrv_dirty_bitmap_get_persistence(bitmap) &&
167bb4e58c6SEric Blake bdrv_remove_persistent_dirty_bitmap(bs, name, errp) < 0)
168bb4e58c6SEric Blake {
169bb4e58c6SEric Blake return NULL;
170bb4e58c6SEric Blake }
171bb4e58c6SEric Blake
172bb4e58c6SEric Blake if (release) {
173bb4e58c6SEric Blake bdrv_release_dirty_bitmap(bitmap);
174bb4e58c6SEric Blake }
175bb4e58c6SEric Blake
176bb4e58c6SEric Blake if (bitmap_bs) {
177bb4e58c6SEric Blake *bitmap_bs = bs;
178bb4e58c6SEric Blake }
179bb4e58c6SEric Blake
180bb4e58c6SEric Blake return release ? NULL : bitmap;
181bb4e58c6SEric Blake }
182bb4e58c6SEric Blake
qmp_block_dirty_bitmap_remove(const char * node,const char * name,Error ** errp)183bb4e58c6SEric Blake void qmp_block_dirty_bitmap_remove(const char *node, const char *name,
184bb4e58c6SEric Blake Error **errp)
185bb4e58c6SEric Blake {
186bb4e58c6SEric Blake block_dirty_bitmap_remove(node, name, true, NULL, errp);
187bb4e58c6SEric Blake }
188bb4e58c6SEric Blake
189bb4e58c6SEric Blake /**
190bb4e58c6SEric Blake * Completely clear a bitmap, for the purposes of synchronizing a bitmap
191bb4e58c6SEric Blake * immediately after a full backup operation.
192bb4e58c6SEric Blake */
qmp_block_dirty_bitmap_clear(const char * node,const char * name,Error ** errp)193bb4e58c6SEric Blake void qmp_block_dirty_bitmap_clear(const char *node, const char *name,
194bb4e58c6SEric Blake Error **errp)
195bb4e58c6SEric Blake {
196bb4e58c6SEric Blake BdrvDirtyBitmap *bitmap;
197bb4e58c6SEric Blake BlockDriverState *bs;
198bb4e58c6SEric Blake
199bb4e58c6SEric Blake bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
200bb4e58c6SEric Blake if (!bitmap || !bs) {
201bb4e58c6SEric Blake return;
202bb4e58c6SEric Blake }
203bb4e58c6SEric Blake
204bb4e58c6SEric Blake if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, errp)) {
205bb4e58c6SEric Blake return;
206bb4e58c6SEric Blake }
207bb4e58c6SEric Blake
208bb4e58c6SEric Blake bdrv_clear_dirty_bitmap(bitmap, NULL);
209bb4e58c6SEric Blake }
210bb4e58c6SEric Blake
qmp_block_dirty_bitmap_enable(const char * node,const char * name,Error ** errp)211bb4e58c6SEric Blake void qmp_block_dirty_bitmap_enable(const char *node, const char *name,
212bb4e58c6SEric Blake Error **errp)
213bb4e58c6SEric Blake {
214bb4e58c6SEric Blake BlockDriverState *bs;
215bb4e58c6SEric Blake BdrvDirtyBitmap *bitmap;
216bb4e58c6SEric Blake
217bb4e58c6SEric Blake bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
218bb4e58c6SEric Blake if (!bitmap) {
219bb4e58c6SEric Blake return;
220bb4e58c6SEric Blake }
221bb4e58c6SEric Blake
222bb4e58c6SEric Blake if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
223bb4e58c6SEric Blake return;
224bb4e58c6SEric Blake }
225bb4e58c6SEric Blake
226bb4e58c6SEric Blake bdrv_enable_dirty_bitmap(bitmap);
227bb4e58c6SEric Blake }
228bb4e58c6SEric Blake
qmp_block_dirty_bitmap_disable(const char * node,const char * name,Error ** errp)229bb4e58c6SEric Blake void qmp_block_dirty_bitmap_disable(const char *node, const char *name,
230bb4e58c6SEric Blake Error **errp)
231bb4e58c6SEric Blake {
232bb4e58c6SEric Blake BlockDriverState *bs;
233bb4e58c6SEric Blake BdrvDirtyBitmap *bitmap;
234bb4e58c6SEric Blake
235bb4e58c6SEric Blake bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp);
236bb4e58c6SEric Blake if (!bitmap) {
237bb4e58c6SEric Blake return;
238bb4e58c6SEric Blake }
239bb4e58c6SEric Blake
240bb4e58c6SEric Blake if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) {
241bb4e58c6SEric Blake return;
242bb4e58c6SEric Blake }
243bb4e58c6SEric Blake
244bb4e58c6SEric Blake bdrv_disable_dirty_bitmap(bitmap);
245bb4e58c6SEric Blake }
246bb4e58c6SEric Blake
block_dirty_bitmap_merge(const char * dst_node,const char * dst_bitmap,BlockDirtyBitmapOrStrList * bms,HBitmap ** backup,Error ** errp)2476a0f7ff7SMarkus Armbruster BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *dst_node,
2486a0f7ff7SMarkus Armbruster const char *dst_bitmap,
2491466ef6cSVladimir Sementsov-Ogievskiy BlockDirtyBitmapOrStrList *bms,
250bb4e58c6SEric Blake HBitmap **backup, Error **errp)
251bb4e58c6SEric Blake {
252bb4e58c6SEric Blake BlockDriverState *bs;
25358cbfbdfSVladimir Sementsov-Ogievskiy BdrvDirtyBitmap *dst, *src;
2541466ef6cSVladimir Sementsov-Ogievskiy BlockDirtyBitmapOrStrList *lst;
2556a0f7ff7SMarkus Armbruster const char *src_node, *src_bitmap;
25658cbfbdfSVladimir Sementsov-Ogievskiy HBitmap *local_backup = NULL;
257bb4e58c6SEric Blake
258b4ad82aaSEmanuele Giuseppe Esposito GLOBAL_STATE_CODE();
259b4ad82aaSEmanuele Giuseppe Esposito
2606a0f7ff7SMarkus Armbruster dst = block_dirty_bitmap_lookup(dst_node, dst_bitmap, &bs, errp);
261bb4e58c6SEric Blake if (!dst) {
262bb4e58c6SEric Blake return NULL;
263bb4e58c6SEric Blake }
264bb4e58c6SEric Blake
265bb4e58c6SEric Blake for (lst = bms; lst; lst = lst->next) {
266bb4e58c6SEric Blake switch (lst->value->type) {
267bb4e58c6SEric Blake case QTYPE_QSTRING:
2686a0f7ff7SMarkus Armbruster src_bitmap = lst->value->u.local;
2696a0f7ff7SMarkus Armbruster src = bdrv_find_dirty_bitmap(bs, src_bitmap);
270bb4e58c6SEric Blake if (!src) {
2716a0f7ff7SMarkus Armbruster error_setg(errp, "Dirty bitmap '%s' not found", src_bitmap);
27258cbfbdfSVladimir Sementsov-Ogievskiy goto fail;
273bb4e58c6SEric Blake }
274bb4e58c6SEric Blake break;
275bb4e58c6SEric Blake case QTYPE_QDICT:
2766a0f7ff7SMarkus Armbruster src_node = lst->value->u.external.node;
2776a0f7ff7SMarkus Armbruster src_bitmap = lst->value->u.external.name;
2786a0f7ff7SMarkus Armbruster src = block_dirty_bitmap_lookup(src_node, src_bitmap, NULL, errp);
279bb4e58c6SEric Blake if (!src) {
28058cbfbdfSVladimir Sementsov-Ogievskiy goto fail;
281bb4e58c6SEric Blake }
282bb4e58c6SEric Blake break;
283bb4e58c6SEric Blake default:
284bb4e58c6SEric Blake abort();
285bb4e58c6SEric Blake }
286bb4e58c6SEric Blake
28758cbfbdfSVladimir Sementsov-Ogievskiy /* We do backup only for first merge operation */
28858cbfbdfSVladimir Sementsov-Ogievskiy if (!bdrv_merge_dirty_bitmap(dst, src,
28958cbfbdfSVladimir Sementsov-Ogievskiy local_backup ? NULL : &local_backup,
29058cbfbdfSVladimir Sementsov-Ogievskiy errp))
29158cbfbdfSVladimir Sementsov-Ogievskiy {
29258cbfbdfSVladimir Sementsov-Ogievskiy goto fail;
293bb4e58c6SEric Blake }
294bb4e58c6SEric Blake }
295bb4e58c6SEric Blake
29658cbfbdfSVladimir Sementsov-Ogievskiy if (backup) {
29758cbfbdfSVladimir Sementsov-Ogievskiy *backup = local_backup;
29858cbfbdfSVladimir Sementsov-Ogievskiy } else {
29958cbfbdfSVladimir Sementsov-Ogievskiy hbitmap_free(local_backup);
300775b30b3SVladimir Sementsov-Ogievskiy }
301bb4e58c6SEric Blake
302bb4e58c6SEric Blake return dst;
30358cbfbdfSVladimir Sementsov-Ogievskiy
30458cbfbdfSVladimir Sementsov-Ogievskiy fail:
30558cbfbdfSVladimir Sementsov-Ogievskiy if (local_backup) {
30658cbfbdfSVladimir Sementsov-Ogievskiy bdrv_restore_dirty_bitmap(dst, local_backup);
30758cbfbdfSVladimir Sementsov-Ogievskiy }
30858cbfbdfSVladimir Sementsov-Ogievskiy
30958cbfbdfSVladimir Sementsov-Ogievskiy return NULL;
310bb4e58c6SEric Blake }
311bb4e58c6SEric Blake
qmp_block_dirty_bitmap_merge(const char * node,const char * target,BlockDirtyBitmapOrStrList * bitmaps,Error ** errp)312bb4e58c6SEric Blake void qmp_block_dirty_bitmap_merge(const char *node, const char *target,
3131466ef6cSVladimir Sementsov-Ogievskiy BlockDirtyBitmapOrStrList *bitmaps,
314bb4e58c6SEric Blake Error **errp)
315bb4e58c6SEric Blake {
316bb4e58c6SEric Blake block_dirty_bitmap_merge(node, target, bitmaps, NULL, errp);
317bb4e58c6SEric Blake }
318