1 /* 2 * QEMU block dirty bitmap QMP commands 3 * 4 * Copyright (c) 2003-2008 Fabrice Bellard 5 * 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. 8 * 9 * This file incorporates work covered by the following copyright and 10 * permission notice: 11 * 12 * Copyright (c) 2003-2008 Fabrice Bellard 13 * 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: 20 * 21 * The above copyright notice and this permission notice shall be included in 22 * all copies or substantial portions of the Software. 23 * 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. 31 */ 32 33 #include "qemu/osdep.h" 34 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" 40 41 /** 42 * block_dirty_bitmap_lookup: 43 * Return a dirty bitmap (if present), after validating 44 * the node reference and bitmap names. 45 * 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. 50 * 51 * @return: A bitmap object on success, or NULL on failure. 52 */ 53 BdrvDirtyBitmap *block_dirty_bitmap_lookup(const char *node, 54 const char *name, 55 BlockDriverState **pbs, 56 Error **errp) 57 { 58 BlockDriverState *bs; 59 BdrvDirtyBitmap *bitmap; 60 61 GLOBAL_STATE_CODE(); 62 63 if (!node) { 64 error_setg(errp, "Node cannot be NULL"); 65 return NULL; 66 } 67 if (!name) { 68 error_setg(errp, "Bitmap name cannot be NULL"); 69 return NULL; 70 } 71 bs = bdrv_lookup_bs(node, node, NULL); 72 if (!bs) { 73 error_setg(errp, "Node '%s' not found", node); 74 return NULL; 75 } 76 77 bitmap = bdrv_find_dirty_bitmap(bs, name); 78 if (!bitmap) { 79 error_setg(errp, "Dirty bitmap '%s' not found", name); 80 return NULL; 81 } 82 83 if (pbs) { 84 *pbs = bs; 85 } 86 87 return bitmap; 88 } 89 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) 95 { 96 BlockDriverState *bs; 97 BdrvDirtyBitmap *bitmap; 98 AioContext *aio_context; 99 100 if (!name || name[0] == '\0') { 101 error_setg(errp, "Bitmap name cannot be empty"); 102 return; 103 } 104 105 bs = bdrv_lookup_bs(node, node, errp); 106 if (!bs) { 107 return; 108 } 109 110 aio_context = bdrv_get_aio_context(bs); 111 aio_context_acquire(aio_context); 112 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; 118 } 119 } else { 120 /* Default to cluster size, if available: */ 121 granularity = bdrv_get_default_bitmap_granularity(bs); 122 } 123 124 if (!has_persistent) { 125 persistent = false; 126 } 127 128 if (!has_disabled) { 129 disabled = false; 130 } 131 132 if (persistent && 133 !bdrv_can_store_new_dirty_bitmap(bs, name, granularity, errp)) 134 { 135 goto out; 136 } 137 138 bitmap = bdrv_create_dirty_bitmap(bs, granularity, name, errp); 139 if (bitmap == NULL) { 140 goto out; 141 } 142 143 if (disabled) { 144 bdrv_disable_dirty_bitmap(bitmap); 145 } 146 147 bdrv_dirty_bitmap_set_persistence(bitmap, persistent); 148 149 out: 150 aio_context_release(aio_context); 151 } 152 153 BdrvDirtyBitmap *block_dirty_bitmap_remove(const char *node, const char *name, 154 bool release, 155 BlockDriverState **bitmap_bs, 156 Error **errp) 157 { 158 BlockDriverState *bs; 159 BdrvDirtyBitmap *bitmap; 160 AioContext *aio_context; 161 162 GLOBAL_STATE_CODE(); 163 164 bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp); 165 if (!bitmap || !bs) { 166 return NULL; 167 } 168 169 aio_context = bdrv_get_aio_context(bs); 170 aio_context_acquire(aio_context); 171 172 if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_BUSY | BDRV_BITMAP_RO, 173 errp)) { 174 aio_context_release(aio_context); 175 return NULL; 176 } 177 178 if (bdrv_dirty_bitmap_get_persistence(bitmap) && 179 bdrv_remove_persistent_dirty_bitmap(bs, name, errp) < 0) 180 { 181 aio_context_release(aio_context); 182 return NULL; 183 } 184 185 if (release) { 186 bdrv_release_dirty_bitmap(bitmap); 187 } 188 189 if (bitmap_bs) { 190 *bitmap_bs = bs; 191 } 192 193 aio_context_release(aio_context); 194 return release ? NULL : bitmap; 195 } 196 197 void qmp_block_dirty_bitmap_remove(const char *node, const char *name, 198 Error **errp) 199 { 200 block_dirty_bitmap_remove(node, name, true, NULL, errp); 201 } 202 203 /** 204 * Completely clear a bitmap, for the purposes of synchronizing a bitmap 205 * immediately after a full backup operation. 206 */ 207 void qmp_block_dirty_bitmap_clear(const char *node, const char *name, 208 Error **errp) 209 { 210 BdrvDirtyBitmap *bitmap; 211 BlockDriverState *bs; 212 213 bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp); 214 if (!bitmap || !bs) { 215 return; 216 } 217 218 if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, errp)) { 219 return; 220 } 221 222 bdrv_clear_dirty_bitmap(bitmap, NULL); 223 } 224 225 void qmp_block_dirty_bitmap_enable(const char *node, const char *name, 226 Error **errp) 227 { 228 BlockDriverState *bs; 229 BdrvDirtyBitmap *bitmap; 230 231 bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp); 232 if (!bitmap) { 233 return; 234 } 235 236 if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) { 237 return; 238 } 239 240 bdrv_enable_dirty_bitmap(bitmap); 241 } 242 243 void qmp_block_dirty_bitmap_disable(const char *node, const char *name, 244 Error **errp) 245 { 246 BlockDriverState *bs; 247 BdrvDirtyBitmap *bitmap; 248 249 bitmap = block_dirty_bitmap_lookup(node, name, &bs, errp); 250 if (!bitmap) { 251 return; 252 } 253 254 if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_ALLOW_RO, errp)) { 255 return; 256 } 257 258 bdrv_disable_dirty_bitmap(bitmap); 259 } 260 261 BdrvDirtyBitmap *block_dirty_bitmap_merge(const char *dst_node, 262 const char *dst_bitmap, 263 BlockDirtyBitmapOrStrList *bms, 264 HBitmap **backup, Error **errp) 265 { 266 BlockDriverState *bs; 267 BdrvDirtyBitmap *dst, *src; 268 BlockDirtyBitmapOrStrList *lst; 269 const char *src_node, *src_bitmap; 270 HBitmap *local_backup = NULL; 271 272 GLOBAL_STATE_CODE(); 273 274 dst = block_dirty_bitmap_lookup(dst_node, dst_bitmap, &bs, errp); 275 if (!dst) { 276 return NULL; 277 } 278 279 for (lst = bms; lst; lst = lst->next) { 280 switch (lst->value->type) { 281 case QTYPE_QSTRING: 282 src_bitmap = lst->value->u.local; 283 src = bdrv_find_dirty_bitmap(bs, src_bitmap); 284 if (!src) { 285 error_setg(errp, "Dirty bitmap '%s' not found", src_bitmap); 286 goto fail; 287 } 288 break; 289 case QTYPE_QDICT: 290 src_node = lst->value->u.external.node; 291 src_bitmap = lst->value->u.external.name; 292 src = block_dirty_bitmap_lookup(src_node, src_bitmap, NULL, errp); 293 if (!src) { 294 goto fail; 295 } 296 break; 297 default: 298 abort(); 299 } 300 301 /* We do backup only for first merge operation */ 302 if (!bdrv_merge_dirty_bitmap(dst, src, 303 local_backup ? NULL : &local_backup, 304 errp)) 305 { 306 goto fail; 307 } 308 } 309 310 if (backup) { 311 *backup = local_backup; 312 } else { 313 hbitmap_free(local_backup); 314 } 315 316 return dst; 317 318 fail: 319 if (local_backup) { 320 bdrv_restore_dirty_bitmap(dst, local_backup); 321 } 322 323 return NULL; 324 } 325 326 void qmp_block_dirty_bitmap_merge(const char *node, const char *target, 327 BlockDirtyBitmapOrStrList *bitmaps, 328 Error **errp) 329 { 330 block_dirty_bitmap_merge(node, target, bitmaps, NULL, errp); 331 } 332